# Understanding the JavaScript Event Loop
JavaScript runs on a single thread, yet it handles thousands of asynchronous operations without blocking. The event loop is the mechanism that makes this possible.
## The Call Stack
Every function call is pushed onto the call stack and popped off when it returns. If a function takes too long, it blocks everything else — which is why heavy synchronous code freezes the browser.
## Web APIs and the Task Queue
Asynchronous operations like `setTimeout`, DOM events, or network requests aren't handled by the JavaScript engine directly — they're delegated to browser (or Node.js) APIs. Once complete, their callback is placed in a task queue, waiting for the call stack to be empty.
## The Microtask Queue
Promises use a separate microtask queue, which has higher priority than the regular task queue. After each task, the event loop drains the entire microtask queue before moving to the next task — this is why Promise callbacks often run before `setTimeout` callbacks, even with a 0ms delay.
```javascript
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
// Output: 1, 4, 3, 2
```
## Why This Matters
Understanding the event loop explains why UI freezes happen, why `async/await` code sometimes executes in an unexpected order, and how to reason about timing bugs in real applications.
## Conclusion
The event loop isn't just a theory question — it directly explains the behavior you'll debug in real async JavaScript code, especially once Promises and timers start interacting.
Back to Blogs
Understanding the JavaScript Event Loop
How JavaScript handles asynchronous code with a single thread — the call stack, task queue, and microtask queue explained simply.
13 Aug 2026
6 min read