Learning outcomes
- Distinguish microtasks from macrotasks
- Avoid event loop starvation in browser/Node
Mental model
JavaScript event loops maintain two distinct queues: the Macrotask Queue (setTimeout, setInterval, I/O) and the Microtask Queue (Promise.then, queueMicrotask, process.nextTick).
Theory
After every synchronous call stack frame empties, the event loop drains the entire Microtask Queue to completion before processing the next macrotask or performing DOM layout repaints. An infinite loop of microtasks (Promise.resolve().then(...)) starves the macrotask queue and freezes browser UI rendering.
export async function traceExecutionOrder(): Promise<string[]> {
const logs: string[] = [];
logs.push("1: Sync Start");
setTimeout(() => logs.push("5: Macrotask (setTimeout)"), 0);
Promise.resolve().then(() => {
logs.push("3: Microtask 1");
}).then(() => {
logs.push("4: Microtask 2");
});
logs.push("2: Sync End");
await new Promise((resolve) => setTimeout(resolve, 10));
return logs;
}
Alternatives and trade-offs
setTimeout(fn, 0) schedules execution in the next macrotask tick. queueMicrotask(fn) schedules immediate execution after the current synchronous stack frame without UI rendering delay.
Failure modes and misconceptions
- Async/Await is not multithreaded:
asyncfunctions do not run on background CPU threads; they execute on the main event loop. - Microtask Starvation: Infinite microtask loops block the event loop permanently, preventing UI events or network callbacks from firing.
Decision scenario
When breaking up long-running UI computations, yield using setTimeout or requestAnimationFrame so the browser can process user inputs and render frames between chunks.
Learning outcomes
- Compare microtask queue priority against macrotask processing.
- Explain execution order across Promises, async/await, and timers.
- Prevent microtask queue starvation in high-throughput applications.
Trade-offs
Microtasks execute immediately after synchronous code without render delays, but un-bounded microtask recursion will freeze user interface interactions.
Evidence assessment
Theory and decision mastery
Decision scenario
A developer needs to break up a large synchronous computation loop so the browser UI stays responsive to user clicks.
Which scheduling approach allows the browser to render frames between chunk batches?
Primary sources
- TypeScript 5.4 Language Specification & Type System Mechanics — Microsoft, verified 2026-07-22