JavaScriptの非同期処理はメインスレッドで実行される
JavaScript Primer 非同期処理:コールバック/Promise/Async Function を読んでいて、自分はずっとJSの非同期処理はマルチスレッドで行われていると勘違いしていたことに気づいた
前提として、JSは基本的にブラウザのメインスレッドで実行される。例外として、Web Worker APIを使えばメインスレッド以外でも実行できる(並行処理)
そして、非同期処理もメインスレッドで実行される
が、非同期処理は一度メインスレッドから外れて後続の処理を行い、ある処理を終えたらメインスレッドに戻って実行される
メインスレッドから一時的に離れるとは…?
これを理解するにはJSのイベントループのメカニズムを知っておく必要がある
イベントループに関しては以下の記事の説明と図がわかりやすかった JavaScriptがブラウザでどのように動くのか | メルカリエンジニアリング
以下、上記記事から引用
- ブラウザ上で読み込まれた JavaScript が、JavaScript エンジンのコールスタック上で実行される
- コールスタック上で実行中に非同期関数が呼び出されると、非同期関数の引数として渡されたコールバック関数は Web APIs に送られる
- Web APIs に送られたコールバック関数は、条件を満たすまでは Web APIs で待機する
- Web APIs で待機しているコールバック関数は、条件を満たすとコールバックキューに追加される
- コールバックキューに追加されたコールバック関数は、コールスタックで実行中の関数が空になるまで待機する
- コールスタックが空になると、コールバックキューで待機しているコールバック関数は、イベントループによってコールスタックに追加される
- コールスタックに追加されたコールバック関数が実行される
非同期処理がメインスレッドから外れるというのは、上記の2に該当する
コールスタックに追加された関数はLIFO方式(後入れ先出し)で処理される コールバックキューはFIFO方式(先入れ先出し)で処理される
【図解】1から学ぶ JavaScript の 非同期処理 - Qiita の説明も非常にわかりやすかった
マウスが意図せずダブルクリックになってしまう問題の結末
2022-06-30 RubyのHash#fetchとHash#[] / Logicoolのマウスが意図せずダブルクリックになってしまう に書いた、意図せずダブルクリックになってしまう問題は結局その後起こっていない
おそらく10秒間クリックしまくったのが効いたのだと思う
ひとまず一件落着したので様子見する