HeadlinesBriefing favicon HeadlinesBriefing.com

JavaScript Event Loop: Why setTimeout(fn, 0) Doesn't Run Immediately

DEV Community •
×

JavaScript's Event Loop and Concurrency Model are often misunderstood. Despite being single-threaded, JavaScript can handle multiple operations without blocking, thanks to its event-driven architecture. This model powers non-blocking I/O, making JavaScript feel multithreaded even when it isn't.

The key to this functionality lies in the Call Stack, Web APIs, and Task Queues. The Call Stack manages function execution, while Web APIs handle asynchronous operations like `setTimeout`. When a Web API completes, it pushes callbacks into the Task Queue, which holds tasks waiting to be executed.

A critical aspect is the Microtask Queue, which has higher priority than the Task Queue. Microtasks, such as Promise callbacks, are processed before any macrotasks. This explains why `setTimeout(fn, 0)` doesn't run immediately; it waits for the Call Stack and Microtask Queue to clear first.

For React developers, understanding this model is crucial. React 18+ automatically batches state updates in event handlers, optimizing re-renders. Additionally, `useEffect` runs after rendering as a microtask, affecting the timing of side effects.