JavaScript
WebWorkers

JavaScriptの非同期処理を並列処理と勘違いしていませんか?

More than 1 year has passed since last update.

*初心者から中級者になろうとしてる人向けの記事です.
*読みやすさを改善しました.(久々Qiitaで適当に書きすぎました..)


この記事を書くにあたり..

いわゆるカメラアプリをブラウザで実装するにあたり,canvas要素をpng形式に変換する処理が150msほどかかってしまっていて,ブラウザに映し出される映像がカクついてしまったという問題が発生しました.

その問題を解決する中で,Web上で色々な記事を読んでいると,JavaScriptの非同期処理を並列処理と勘違いしている人が結構いたので,今回はそんな初心者から中級者になろうとしている人のための記事です.

*JavaScript上級者の方は.何か間違っていることがあればコメントください.


そもそも非同期処理とは

プログラムが記述された通りに実行されるものを同期処理と言います.

しかし,同期処理だと,1行のプログラムに時間がかかったら,全体が重くなってしまいます.

(例えば,サーバーにリクエストしてそれが何秒もかかって,UIまでもがフリーズしたら,何だこのページは!ってなりますよね)

そこで考え出されたのが非同期処理で,処理が実行できるようになるのを待ち,実行できるようになってから実行するといった処理です.

例えば,イベント処理などが非同期処理にあたりますね.ボタンがクリックされたら実行するといった具合です.

setTimeout()やsetInterval()なども非同期処理にあたります.


JavaScriptにおける非同期処理

さて,ここからが本題です.

非同期処理はメインスレッドではなく別のスレッドで実行しているイメージがあるかもしれません.

その認識は間違っています.

JavaScriptは,シングルスレッドの実装しかできません(後述するWebWorkersを使えばできますが..).

非同期処理を実装せずにプログラムを書くとメインプログラムが単一スレッドを独占してしまいます.非同期処理を実装すると,実行を待っている関数待ちの行列にコールバック関数が割り込みされます.下図を参照してください.発火してすぐにコールバックが実行されるのではなく,実行中の関数が実行終わってから実行されるようです.(処理は関数単位で実行される)

非同期処理.png


並行処理と並列処理

並列処理とは,まさにマルチスレッドでプログラムを実行し計算負荷を分散させる処理です.

似たような単語に並行処理というものがあります.

並行処理は,あくまで処理を順不同に行う処理です.人間にとってみればあたかも同時に行われているように見えてしまう処理のことです.

ですから,イベント処理やpromise等は並行処理に当たるのです.

並行処理では,私の作成しているカメラアプリで画像を書き出している途中で映像が止まってしまいます.


JavaScriptでマルチスレッドを実行するには..

JSをマルチスレッドで実行するにはWebWorkersというAPIを使うと実装できます.

ここでは,詳しく書きませんが,このAPIを用いるとマルチスレッドで実装できます.

しかし,WebWorkersAPIでは,DOMを取得できないのでcanvas要素を取得できません.

困った...

そこで私は,iframeを用いて...という話は今回の話題とずれるので後日書きます.

非同期処理が並列処理と勘違いしていた人が一人でも救済されることを願っています.

おすすめ

今回の話題のようなことをまとめてあるブログをまとめてある方のリンク