Fossils🧠 ConceptualHow Does the JavaScript Event Loop Work?
ðŸĶ–DinosaurJavaScriptBrowserAsync

How Does the JavaScript Event Loop Work?

The question that separates developers who write async code from developers who understand async code. Your answer reveals your mental model.

How Does the JavaScript Event Loop Work?

Interview Question: "Explain the JavaScript event loop. What's the difference between microtasks and macrotasks?"

The Senior Answer

"JavaScript is single-threaded but non-blocking. The event loop is the scheduling mechanism that makes this work. It has a simple algorithm: run synchronous code to completion, drain ALL microtasks, optionally render, then pick ONE macrotask. Repeat."

The Architecture

Call Stack → empty? → Drain Microtask Queue (ALL) → Render? → Pick ONE Macrotask → Repeat

Microtasks vs Macrotasks

"Microtasks (Promise.then, queueMicrotask, MutationObserver) have priority — ALL microtasks drain before the next macrotask or render. Macrotasks (setTimeout, setInterval, I/O) run one at a time with the browser getting a chance to render between them."

The Critical Insight

"This means a chain of microtasks can starve rendering. If you resolve a Promise that schedules another Promise that schedules another — the browser can't paint until the chain finishes. This is why requestAnimationFrame exists for visual updates and why React's scheduler yields to the browser between work units."

The Trick Question

console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
queueMicrotask(() => console.log('4'));
console.log('5');

Output: 1, 5, 3, 4, 2

"Sync first (1, 5). Then microtasks in order (3, 4). Then macrotasks (2). The key insight: setTimeout(fn, 0) doesn't mean 'run immediately' — it means 'run in the next macrotask, after all microtasks are drained.'"

Follow-Ups

"Where does requestAnimationFrame fit?"

"rAF callbacks run at a specific point — after microtasks drain, before the next paint, once per frame (~16ms). It's synchronized with the display refresh, making it the right tool for animations and DOM measurements."

"How does async/await relate?"

"Code after await is essentially a .then() callback — it runs as a microtask. async function f() { await x; doStuff(); } is equivalent to x.then(() => doStuff()) in terms of event loop scheduling."

"How does React use the event loop?"

"React 18's concurrent renderer uses MessageChannel (a macrotask mechanism) to yield control back to the browser between work units. This is how startTransition keeps the UI responsive — React does some rendering work, yields so the browser can process input and paint, then resumes."

Red Flags

  • Saying "setTimeout(fn, 0) runs immediately"
  • Not knowing microtasks have priority over macrotasks
  • Missing the render step in the event loop
  • Not understanding that microtask chains can block rendering