JavaScript はシングルスレッドで動作するため、一度に一つのことしかできません。イベントループは、ブロックすることなく非同期処理を扱えるようにする仕組みです。コールスタックを実行し、スタックが空になると、キューからコールバックを取り出します。
優先度の異なる 2 つのキューがあります。
- マイクロタスク: Promise のコールバック(
.then)、。各タスクの後、レンダリングの前に処理されます。
JavaScript はシングルスレッドで動作するため、一度に一つのことしかできません。イベントループは、ブロックすることなく非同期処理を扱えるようにする仕組みです。コールスタックを実行し、スタックが空になると、キューからコールバックを取り出します。
優先度の異なる 2 つのキューがあります。
.then)、。各タスクの後、レンダリングの前に処理されます。queueMicrotasksetTimeout、I/O、UI イベント。ループの 1 反復につき 1 つ処理されます。console.log("1"); // sync
setTimeout(() => console.log("2"), 0); // macrotask
Promise.resolve().then(() => console.log("3")); // microtask
console.log("4"); // sync
// Output: 1, 4, 3, 2
1、4。3。2。だからこそ、両方とも「非同期」であっても、Promise.then は常に setTimeout(…, 0) よりも先に実行されます。マイクロタスクが優先されるためです。
// ❌ blocks the single thread — UI freezes for 5 seconds
while (Date.now() - start < 5000) {}
長い同期処理はすべて(レンダリング、クリック)をブロックします。重い CPU 処理はWeb Worker(本物の別スレッド)にオフロードしましょう。
ループを理解すると、非同期の順序、なぜ promise がタイマーより先に解決されるのか、そしてなぜメインスレッドを決してブロックしてはいけないのかがわかります。これはすべての非同期 JavaScript の中核となるメンタルモデルです。