TypeScript/非同期/Lesson 02
イベントループ — Microtask vs Macrotask、型でキューを表現する
30分·theory
このチャプター
2/7
TypeScript
イベントループ — Microtask vs Macrotask、型でキューを表現する
💡 なぜ学ぶべきか? — キューが見えれば、デバッグが見える
🎯
PromiseがsetTimeoutより先に実行される理由 — マイクロタスクキューはマクロタスクキューより優先されます。面接の定番問題です。
💼
TypeScriptはキュー自体を変えませんが、キューに入れる関数のシグネチャを強制できます。誤ったコールバックをキューに入れるミスをコンパイル時に防ぎます。
⚡
`queueMicrotask`・`setImmediate`・`requestAnimationFrame`のコールバックシグネチャをTypeScriptは正確に把握しており、誤った呼び出しパターンを防ぎます。
🔗
非同期コードの順序バグ(レースコンディション)は型システムでは検出できません — ただし、キューモデルを理解していなければそのようなバグをデバッグすることもできません。
🏢 실무에서는
Reactの`useEffect`、Next.jsの`useTransition`、Vueの`nextTick` — これらはすべてマイクロタスク・マクロタスクキューの上に構築されています。`setState`の直後にDOMを読むと古い値が返る理由、`await`の一行の間にpropsが変わりうる理由 — すべてイベントループモデルで説明できます。
Call Stack → Web API → Queue → Loop
1. イベントループの 4 つの構成要素
2. ループの 1 サイクル
1. Call Stack が空になったら、Microtask Queue をすべて空にします。
2. 次に Macrotask Queue から1 件だけ取り出します。
3. 再び Microtask Queue を空にします。
4. 繰り返し。
3. TypeScript が守ってくれる部分
4. async/await がキューと出会う地点
💡 💡 イベントループ面接の定番 + TypeScript が検出できるミス
1. Promise が setTimeout(0) より先に実行される理由
Microtask キューの優先度: 1 サイクル内で microtask をすべて処理してから、macrotask を 1 件処理します。
2. await 以降のコードは常に microtask
3. queueMicrotask のコールバックは引数なし — TypeScript が強制
4. setTimeout の可変引数を TypeScript は把握している
5. 無限 microtask はメインスレッドを止める
TypeScript では検出不可 — コードレビューで防ぐこと。
⚡ 実際に試してみよう — イベントループの順序
同期 → microtask → macrotask の順序を直接確認します。
✏️ JS 코드
📟 コンソール出力
▶ 実行ボタンを押してください
⚠️ ブラウザのサンドボックスで実行 — console.log()のみ対応、alert/fetchは不可
理解度チェック
次のコードの出力順序は?
```ts
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
```
先に読むとよい概念: 同期 vs 非同期 — コールバックシグネチャまで保護
次のおすすめ: Promise<T> — JS vs TS の違い