setTimeout 0msの実行順序
📝 問題の再掲
Q43: 以下のコードの出力順は?
console.log("A");
setTimeout(() => console.log("B"), 0);
console.log("C");
正答: A → C → B
⚠️ よくある間違い
「0ミリ秒なら即実行されるはず」と思いがちですが、setTimeout は 0ms でも今の処理がすべて終わってから実行されます。
📖 段階的な説明
ステップ1:JavaScriptは1つずつ処理する
JavaScriptは「シングルスレッド」で、一度に1つの処理しかできません。
ステップ2:2つの待ち行列がある
- コールスタック — 今すぐ実行するコードの列
- タスクキュー — 後で実行するコードの待機列(setTimeout等)
ステップ3:実行の流れ
1. console.log("A") → コールスタックで即実行 → "A" 出力
2. setTimeout(fn, 0) → fn をタスクキューに入れる(後回し)
3. console.log("C") → コールスタックで即実行 → "C" 出力
4. コールスタックが空になった!
5. タスクキューから fn を取り出して実行 → "B" 出力
ステップ4:料理で例えると
レストランの注文に例えると:「注文を全部聞いてから(コールスタック)、料理を作り始める(タスクキュー)」。0秒後に作ってと言われても、まず全部の注文を聞き終えてからです。
💻 コード例
console.log("1: 開始");
setTimeout(() => {
console.log("2: setTimeout 0ms");
}, 0);
setTimeout(() => {
console.log("3: setTimeout 100ms");
}, 100);
console.log("4: 終了");
// 出力順: 1 → 4 → 2 → 3
// 同期コード(1,4)が先に全部実行され、
// その後タスクキューの処理(2,3)が順番に実行される
🔗 関連知識
- addEventListener のコールバックも同じ仕組みで動きます(イベント発生時にタスクキューに入る)
- この仕組みを「イベントループ」と呼びます
✅ 確認問題
Q: 以下の出力順は?
setTimeout(() => console.log("X"), 0);
console.log("Y");
console.log("Z");
答えを見る
Y → Z → X。同期コード(Y, Z)が先に実行され、setTimeout のコールバック(X)は最後に実行されます。