Explain the event loop. What does setTimeout(fn, 0) actually do?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
The event loop repeatedly takes the oldest runnable task off a queue and runs it to completion after the current script finishes. setTimeout(fn, 0) schedules fn as a macrotask, so it runs only after synchronous code and all microtasks (promises) complete — never instantly.
Detailed explanation
JavaScript runs on a single thread with a run-to-completion model: one task at a time, no preemption. After each macrotask (script chunk, timer callback, I/O event), the engine drains the entire microtask queue — promise reactions and MutationObservers — before rendering or picking the next macrotask. That ordering is why promise callbacks beat setTimeout even with a 0ms delay. A 0ms timeout isn't 'run immediately'; browsers clamp nested timeouts to ~4ms minimums, and the callback still waits for the stack to clear plus queued microtasks. This model explains UI jank too: any long-running synchronous loop blocks both timers and paint, which is why heavy work gets chunked, debounced, or moved to a Web Worker.
Example
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// Output order: 1, 4, 3, 2
// sync → microtasks (promises) → macrotasks (timers)Interview tip
Recite the exact output of the four-line snippet before explaining — predicting it confidently is the fastest way to prove mastery of this question.
Common mistakes
- Saying setTimeout(0) executes immediately.
- Not knowing promises are microtasks that jump ahead of timers.