Yuri's Blog
ゴールデンレトリバー

JavaScriptのランタイム構成からイベントループを学ぶ

公開日:2024年11月23日

最終更新日:2024年11月23日

JavaScript

こんにちは、Yu_riです。
今回はJavaScriptのイベントループについて以下動画(JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue)で学んだことを記載していきます。

JavaScriptランタイム(実行環境)の構成


① Call Stack(コールスタック) ≒ JavaScriptエンジン
※JavaScriptエンジンにはコールスタックとヒープの2つのプログラムが存在します。

  • JavaScriptのコードを実行している実体
  • 後入れ先出し(LIFO)の構造で実行されている
  • シングルスレッドで実行されているため1度に1つのタスクを実行する
function a() { //コールスタックに入るのは3番目、でも取り除かれるのは1番目
}
function b() { //コールスタックに入るのは2番目、でも取り除かれるのは2番目
    a();
}
function c() { //コールスタックに入るのは1番目、でも取り除かれるのは3番目
    b();
}
c();

つまり関数内の処理が完了する(コールスタックから取り除かれる)まで関数は終了しません。

じゃあ関数内の処理が多かったら?
→当然関数が終わるまでの時間が多くかかることになります。
そのためネットワークリクエストやタイマーなどに長時間実行する必要のあるタスクがあるとスレッドはブロックされてしまうのです。

そこで登場するのが以降の技術です。

② Web APIs

  • ブラウザが提供しているAPIのこと<br>例:Fetch API、TImers API、Geolocation APIなど
  • コールスタックで行う処理をWeb APIsにオフロードすることが可能
    • Web APIsが実行されている間、コールスタックは他の処理を実行できる
  • Web APIsを使用するには大きく「コールバックベース」と「プロミスベース」がある
navigator.geolocation.getCurrentPosition(
    position => console.log(position),
    error => console.log(error)
)

//プロミスベース
fetch("https://sample.com/api/...")
    .then(res => console.log(res))

③ Task Queue(タスクキュー)

  • コールバックベースのWeb APIsを実行された後に実行するコールバック関数(またはイベントハンドラー)が格納されるキューのこと
    • このコールバック関数はAPI実行の成功 or 失敗で実行される関数などのこと
  • コールスタックが空になるまで実行されず待機している(後述する「イベントループ」がチェックしている)

setTimeoutなどで遅延時間を設定した場合、遅延時間の意味は「Web APIsからタスクキューに移るまでの時間(≠実行されるまでの時間)」であることに注意

④ Microtask Queue(マイクロタスクキュー)

  • プロミスベースのWeb APIsを実行された後に実行するコールバック関数が格納されるキューのこと
    • このコールバック関数はAPI実行の成功 or 失敗で実行される関数のこと
  • コールスタックが空になるまで実行されず待機している(後述する「イベントループ」がチェックしている)

⑤ Event Loop(イベントループ)

  • コールスタック、タスクキュー、マイクロタスクキューの状況を管理している
    例)コールスタックが空になったらタスクキューの処理をコールスタックに移動させるなど
  • 優先度は「マイクロタスクキュー タスクキュー」であるためマイクロタスクキューに処理が待機している場合はマイクロタスクキューが空になるまでコールスタックに移す
    その後タスクキューの処理をコールバックに移す