イベントループ:コールスタック・キュー・マイクロタスク
JavaScript の実行を可視化します。コールスタック、タスクキュー、Promise から生じるマイクロタスク、そして非同期処理中も UI がブロックされない理由を学びます。
「イベントループ:コールスタック・キュー・マイクロタスク」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。
JavaScriptはシングルスレッド
JavaScriptは1つのスレッドで実行されるため、一度に1つの処理しか実行できません。それでも、ネットワーク リクエスト、タイマー、UIイベントなど、何千もの非同期処理をブロックせずに処理できます。なぜでしょうか。イベントループがあるからです。
コールスタック
コールスタックは、JavaScriptが現在実行中の関数を追跡する場所です。関数が呼び出されるとフレームがプッシュされ、戻るとフレームがポップされます。スタックがいっぱいになると(無限再帰などの場合)、スタックオーバーフローが発生します。
function c() { /* does something */ }
function b() { c(); }
function a() { b(); }
a();
// Call stack during c():
// c ← top
// b
// a
// (anonymous)Web API — 処理の委譲
JavaScriptが非同期関数(setTimeout、fetch、addEventListener)を呼び出すと、その処理はブラウザーのWeb APIに委譲されます。JavaScriptエンジンは次の行の処理を続け、待機することはありません。
console.log('1');
setTimeout(() => console.log('2'), 0); // handed to Web API
console.log('3');
// Output: 1, 3, 2タスクキュー(マクロタスクキュー)
Web API の操作が完了すると(タイマーが発火した場合や fetch が解決された場合など)、コールバックは タスクキュー(マクロタスクキュー)に入れられます。イベントループは、コールスタックが空になったときだけ、コールバックをコールスタックに移します。
マイクロタスクキュー
Promise は マイクロタスクキュー(優先度の高いキュー)を使用します。各タスクが完了した後、次のタスクが取り出される前に、保留中のマイクロタスクがすべて処理されます。マイクロタスクは必ず次のマクロタスクより先に実行されます。
console.log('1');
setTimeout(() => console.log('timeout'), 0); // macrotask
Promise.resolve().then(() => console.log('promise')); // microtask
console.log('2');
// Output: 1, 2, promise, timeoutイベントループの動作
イベントループのアルゴリズムは次のとおりです。1) コールスタック上の現在のタスクを、空になるまで実行します。2) マイクロタスクキューをすべて処理します。3) 必要に応じて描画します。4) 次のマクロタスクを取り出して、同じ処理を繰り返します。
queueMicrotask()
queueMicrotask(fn) は、Promise を作成せずにコールバックをマイクロタスクキューに登録します。直接使う機会はほとんどありませんが、ライブラリがスケジューリングを実装する仕組みを理解するのに役立ちます。
queueMicrotask(() => console.log('microtask'));
console.log('sync');
// Output: sync, microtask長時間タスクが UI を停止させる理由
同期タスクの実行時間が長すぎると(大量のデータをタイトなループで処理する場合など)、イベントループが UI イベントを処理したり描画したりできなくなります。その結果、ページが停止したようになります。長い処理は setTimeout を使って分割し、イベントループに処理を戻してください。
// Bad — blocks the UI for seconds:
for (let i = 0; i < 10_000_000; i++) { /* heavy work */ }
// Better — yield periodically:
async function processInChunks(items) {
for (let i = 0; i < items.length; i++) {
process(items[i]);
if (i % 100 === 0) await new Promise(r => setTimeout(r, 0)); // yield
}
}Web Workers — 真の並列処理
CPU 負荷の高い処理には、独自のイベントループを持つ別スレッドである Web Worker を使用します。Worker は postMessage を介してメインスレッドと通信します。共有メモリがないため、競合状態も発生しません。
requestAnimationFrame
requestAnimationFrame(callback) は、ブラウザーが次に再描画する前にコールバックを実行するようスケジュールします。JavaScript でアニメーションを制御する場合に使用してください。ディスプレイのリフレッシュレート(通常は 60fps)と同期します。
function animate(timestamp) {
// update positions based on timestamp
element.style.transform = `translateX(${timestamp * 0.1 % 400}px)`;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);イベントループを視覚的に理解する
latentflip.com/loupe のインタラクティブなデモでは、コードを貼り付けて、コールスタック、Web API、タスクキュー、イベントループの動作をスローモーションで確認できます。イベントループの直感的な理解を身につけるのに不可欠です。
確認問題
Promise が解決された後、その .then() コールバックはどのキューで実行されますか?
まとめ:イベントループ
JavaScript はシングルスレッドです。非同期処理は Web API に渡されます。コールバックは、タスクキュー(setTimeout や fetch のコールバック)またはマイクロタスクキュー(Promise)を経由して戻ってきます。イベントループは各タスクの後、次の描画やマクロタスクの前にマイクロタスクをすべて処理します。長時間の同期処理はすべての処理をブロックします。
よくある質問
「イベントループ:コールスタック・キュー・マイクロタスク」レッスンは無料ですか?
はい。「イベントループ:コールスタック・キュー・マイクロタスク」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。
「イベントループ:コールスタック・キュー・マイクロタスク」で何を学びますか?
JavaScript の実行を可視化します。コールスタック、タスクキュー、Promise から生じるマイクロタスク、そして非同期処理中も UI がブロックされない理由を学びます。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Frontend Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「イベントループ:コールスタック・キュー・マイクロタスク」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このFrontend Academyレッスンでコードを書いて実行できますか?
はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- イベントループ:コールスタック・キュー・マイクロタスク
- コールバックとコールバック地獄
- Promise:then・catch・finally・Promise.all
- async/await とエラーハンドリング