🔁

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

2024/06/15に公開

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

https://www.youtube.com/watch?v=eiC58R16hb8&list=PLYiYQVWAjSGMDserRaYZOsYVjsGazJefy&t=51s

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

1. Call Stack(コールスタック) ≒ JavaScriptエンジン

※JavaScriptエンジンにはコールスタックとヒープの2つのプログラムが存在する

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

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

じゃあ関数内の処理が多かったら?
→当然関数が終わるまでの時間が多くかかることになる

そのためネットワークリクエストやタイマーになど長時間実行する必要のあるタスクがあるとスレッドはブロックされてしまう

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

2. Web APIs

  • ブラウザが提供しているAPIのこと
    例: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))

3. Task Queue(タスクキュー)

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

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

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

5. Event Loop(イベントループ)

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

終わり

今回はJavaScriptのイベントループを学ぶという内容でJavaScriptのランタイムの構成をみてきました。
非同期処理のコードを見る・書く時にはこのことを頭にイメージして行っていきたいですね。
今後もJavaScriptだけでなく様々な技術関連の記事を投稿していきます。

Discussion