How Does the JavaScript Event Loop Work?
This is a top-tier question because it bridges language mechanics with browser architecture.
The Architecture
JavaScript is single-threaded but non-blocking. The event loop is the mechanism that makes this possible:
âââââââââââââââ ââââââââââââââââ
â Call Stack â â Web APIs â
â â â (setTimeout,â
â main() âââââââ fetch, â
â fn() â â DOM events)â
ââââââââŽâââââââ ââââââââŽââââââââ
â â
â âââââââââââââââââžâââââââââââ
â â Callback Queue â
â â (macrotasks) â
â âââââââââââââââââŽâââââââââââ
â â
â âââââââââââââââââžâââââââââââ
â â Microtask Queue â
â â (Promises, queueMicro) â
â ââââââââââââââââââââââââââââ
â
Event Loop: Is call stack empty?
â Drain ALL microtasks
â Take ONE macrotask
â RepeatThe Classic Trick Question
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');Output: 1, 4, 3, 2
Why? Synchronous code runs first (1, 4). Then microtasks (Promise â 3). Then macrotasks (setTimeout â 2).
Microtasks vs Macrotasks
| Microtasks | Macrotasks |
|---|---|
| Promise.then/catch/finally | setTimeout / setInterval |
| queueMicrotask() | I/O callbacks |
| MutationObserver | requestAnimationFrame |
| process.nextTick (Node) | UI rendering |
The critical difference: all microtasks drain before the next macrotask. This means Promises always resolve before setTimeout, even with setTimeout(fn, 0).
The Rendering Connection
The browser's rendering pipeline is tied to the event loop:
- Run a macrotask
- Drain all microtasks
- If it's time to render (~16ms for 60fps):
- Run requestAnimationFrame callbacks
- Style calculation â Layout â Paint â Composite
This is why requestAnimationFrame is the right tool for animations â it's synchronized with the browser's render cycle.
Senior Signal
Discuss the event loop in terms of:
- Why it exists â single-threaded but non-blocking I/O
- The queue priority â microtasks always before macrotasks
- Real implications â long microtask chains can block rendering
- Practical usage â choosing between setTimeout, rAF, and queueMicrotask
Understanding the event loop isn't about memorizing output puzzles â it's about predicting how your async code will actually execute.