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 â RepeatMicrotasks 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
requestAnimationFrameexists 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
awaitis essentially a.then()callback â it runs as a microtask.async function f() { await x; doStuff(); }is equivalent tox.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 howstartTransitionkeeps 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