Microtasks vs Macrotasks (Event Loop Deep Dive)
Microtasks vs Macrotasks (Event Loop Deep Dive)
Mastering the JavaScript Event Loop requires understanding the boundary between the Microtask Queue (Job Queue) and the Macrotask Queue (Task Queue). Misunderstanding task scheduling leads to subtle race conditions, delayed rendering frames, and interface freezes.
1. The Two Asynchronous Queues
JavaScript categorizes asynchronous callbacks into two distinct queues with vastly different execution priorities:
| Queue Type | APIs & Triggers | Drain Behavior |
|---|---|---|
| Microtask Queue | Promise.then/catch/finally, queueMicrotask(), process.nextTick (Node), MutationObserver | Drained completely to zero items before moving to rendering or next macrotask |
| Macrotask Queue | setTimeout, setInterval, setImmediate (Node), I/O events, UI clicks/keyboard events | Executes one single task, then cedes control to microtasks and rendering |
2. Execution Order Tracing
Analyze this classic interview test case:
Execution Step-by-Step:
- 1Synchronous code runs first:
- Logs
1. Script Start (Sync) - Schedules
setTimeoutcallback in Macrotask Queue. - Schedules Promise 1 in Microtask Queue.
- Schedules
queueMicrotaskin Microtask Queue. - Logs
6. Script End (Sync)
- 1Call Stack is now empty! Event Loop checks Microtask Queue:
- Runs Promise 1 -> logs
3. Promise 1 (Microtask)-> schedules Promise 2 in Microtask Queue! - Runs
queueMicrotask-> logs5. queueMicrotask (Microtask). - Runs Promise 2 -> logs
4. Promise 2 (Microtask). - Microtask Queue is now completely empty.
- 1Event Loop checks Macrotask Queue:
- Runs
setTimeoutcallback -> logs2. setTimeout (Macrotask).
Final Console Output Order: 1 -> 6 -> 3 -> 5 -> 4 -> 2
3. Microtask Starvation (UI Freeze)
Because the engine must drain the entire Microtask Queue before rendering or moving to the next macrotask, recursively scheduling microtasks will freeze the browser completely:
4. When to Use queueMicrotask()
The queueMicrotask() standard API allows you to schedule a function to run asynchronously after the current synchronous function finishes, but before browser rendering or timer macrotasks:
Practice Quiz
Custom Promise Implementation
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Top-Level Await in ES Modules | Custom Promise Implementation |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.