
JavaScriptの非同期処理、もう迷わない!イベントループとコールスタックの仕組みを徹底解説!
JavaScriptのイベントループとは?
JavaScriptはシングルスレッドで動作しますが、非同期処理を実現するためにイベントループという仕組みを持っています。イベントループは、コールスタック、タスクキュー(またはメッセージキュー)、そしてWeb API(ブラウザ環境の場合)やNode.js API(Node.js環境の場合)といった要素で構成されています。
イベントループの役割は、コールスタックが空になるのを監視し、タスクキューに積まれたタスクを順番にコールスタックに移動させることです。これにより、JavaScriptは非同期処理を効率的に処理し、UIのフリーズを防ぐことができます。
イベントループを理解することで、JavaScriptの非同期処理の挙動を予測し、より効率的なコードを書くことができるようになります。
コールスタックの役割
コールスタックは、JavaScriptエンジンが実行中の関数を追跡するためのデータ構造です。関数が呼び出されると、その関数がコールスタックにプッシュされ、関数の実行が完了すると、コールスタックからポップされます。
コールスタックはLIFO(Last-In, First-Out:後入れ先出し)の原則に従います。つまり、最後にプッシュされた関数が最初にポップされます。
function firstFunction() {
console.log('firstFunction start');
secondFunction();
console.log('firstFunction end');
}
function secondFunction() {
console.log('secondFunction start');
thirdFunction();
console.log('secondFunction end');
}
function thirdFunction() {
console.log('thirdFunction start');
console.log('thirdFunction end');
}
firstFunction();
上記のコードを実行すると、コンソールには次のように出力されます。
firstFunction start
secondFunction start
thirdFunction start
thirdFunction end
secondFunction end
firstFunction end
これは、firstFunction
がコールスタックにプッシュされ、次にsecondFunction
、そしてthirdFunction
がプッシュされるからです。thirdFunction
が完了すると、ポップされ、secondFunction
、firstFunction
の順にポップされます。
イベントループの動作
イベントループは、継続的にコールスタックとタスクキューを監視しています。コールスタックが空になると、イベントループはタスクキューからタスクを取り出し、コールスタックにプッシュします。これにより、非同期処理の結果(例えば、setTimeoutやXMLHttpRequestのコールバック関数)が実行されます。
console.log('start');
setTimeout(function() {
console.log('setTimeout callback');
}, 0);
console.log('end');
上記のコードを実行すると、コンソールには次のように出力されます。
start
end
setTimeout callback
これは、setTimeout
のコールバック関数がタスクキューに追加され、コールスタックが空になった後で実行されるからです。setTimeout
の遅延時間が0であっても、コールバック関数はタスクキューを経由して実行されるため、console.log('end')
の後に実行されます。
この挙動を理解することは、JavaScriptで非同期処理を扱う上で非常に重要です。
タスクキュー(メッセージキュー)
タスクキューは、非同期処理の結果として実行されるコールバック関数が格納される場所です。setTimeout、setInterval、addEventListenerなどの非同期処理によって生成されたタスクは、このキューに追加されます。
イベントループは、コールスタックが空になったときに、このタスクキューからタスクを取り出して実行します。タスクキューはFIFO(First-In, First-Out:先入れ先出し)の原則に従います。
参考リンク
まとめ
JavaScriptのイベントループ、コールスタック、タスクキューの仕組みを理解することで、非同期処理の挙動を正確に把握し、より効率的で信頼性の高いコードを書くことができます。これらの概念は、JavaScriptを深く理解するために不可欠です。