lesson depth
Mastery
not started · 0%

Promises & Microtask Queue

JavaScript event loop, microtasks vs macrotasks, and async execution order.

Freshness: current15 min readComputer Science and Programming

Key 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).

Synchronous Call Stack
Drain Microtask Queue completely
Execute one Macrotask
RequestAnimationFrame render
Repeat Loop Tick
Conceptual teaching model synthesized from:TypeScript 5.4 Language Specification & Type System Mechanics

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.

typescript(16 lines)
1export async function traceExecutionOrder(): Promise<string[]> {
2 const logs: string[] = [];
3 logs.push("1: Sync Start");
4 setTimeout(() => logs.push("5: Macrotask (setTimeout)"), 0);
5
6 Promise.resolve().then(() => {
7 logs.push("3: Microtask 1");
8 }).then(() => {
9 logs.push("4: Microtask 2");
10 });
11
12 logs.push("2: Sync End");
13 await new Promise((resolve) => setTimeout(resolve, 10));
14 return logs;
15}

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

  1. Async/Await is not multithreaded: async functions do not run on background CPU threads; they execute on the main event loop.
  2. Microtask Starvation: Infinite microtask loops block the event loop permanently, preventing UI events or network callbacks from firing.
Reflect before revealing the guide

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.

Prerequisites & Related Concepts (2)

Private notes

0 words
Next