イベントループ:非同期プログラムの中心的な理解

イベントループ(Event Loop)は、ほとんどの現代のウェブブラウザや JavaScript 実行環境で非同期コードの実行を管理するメカニズムです。イベントループは、コードの実行の流れを制御し、イベントの発生、コールバック関数の呼び出し、他の非同期タスクの管理を通じて、プログラムが非同期的なタスクを効率的に処理できるようにします。

イベントループの主要な要素

JavaScriptはシングルスレッド(single-threaded)で動作します。これは、一度に1つのタスクしか実行できないことを意味します。そのため、ネットワークリクエスト、ファイル読み取り、ユーザー入力などのI/O操作が発生した場合、プログラムは待つことなく次のタスクを処理する必要があります。このような非同期タスクを効果的に処理するために、イベントループが使用されます。

  • コールスタック(Call Stack): 現在実行中の関数の呼び出し情報を保存するスタックです。関数が呼び出されると、その関数の情報がスタックに追加され、関数が戻されるとスタックから削除されます。

  • コールバックキュー(Callback Queue): 非同期タスクのコールバック関数が待機するキューです。非同期タスクが完了すると、対応するコールバック関数がコールバックキューに追加されます。

  • イベントループ(Event Loop): コールスタックとコールバックキューを監視し、コールスタックが空である場合にのみ、コールバックキューからコールバック関数を取り出してコールスタックに移動させる役割を果たします。

プログラムの実行結果を見てみましょう。

  1. 開始
  2. 終了
  3. 非同期関数の完了
  4. コールバック関数の実行

プログラムが開始されると、最初に「開始」が出力されます。その後、asyncFunctionは非同期関数であり、setTimeout関数を使用して2秒後にタスクを完了し、コールバック関数を呼び出します。ただし、コールバック関数の実行を待たずに次のコードが実行されます。'終了'が出力されます。2秒を待ったasyncFunctionが実行されます。2秒後、setTimeoutのコールバック関数が実行されます。'非同期関数の完了'が出力されます。最後にsetTimeoutのコールバック関数で定義された内容が実行され、'コールバック関数の実行'が出力されます。

Event Loop

function asyncFunction(callback) {
    setTimeout(function() {
        console.log("非同期関数の完了");
        callback(); 
    }, 2000);
}

console.log("開始");

asyncFunction(function() {
    console.log("コールバック関数の実行");
});

console.log("終了");


イベントループの動作プロセス

  1. コードの実行が開始され、初期の関数呼び出しがスタックに追加されます。
  2. 非同期タスクが発生すると、それらのタスクはバックグラウンドで処理されます。
  3. 非同期タスクが完了すると、コールバック関数がコールバックキューに追加されます。
  4. イベントループは、呼び出しスタックが空であるかどうかを継続的に確認し、スタックが空であればコールバックキューからコールバック関数を取り出して呼び出しスタックに追加します。
  5. 呼び出しスタックに追加された関数が実行される際に、非同期タスクが発生する可能性があり、このプロセスが繰り返されます。