Interview contents
JavaScript Event Loop Explained (2025 Edition)
JavaScript Event Loop: The Ultimate Guide (2025 Edition)
A clear, modern explanation of the event loop, microtasks, macrotasks, timers, promises, and how Node.js and browsers differ.
1. Why the Event Loop Exists
JavaScript runs in a single thread — meaning it can execute only one piece of code at a time.
But real applications need to:
- Fetch data from APIs
- Handle user events
- Read files
- Run timers
- Animate the UI
Executing these synchronously would block the entire app.
➡️ The event loop allows JavaScript to be non-blocking and asynchronous despite being single-threaded.
2. Big Picture Architecture
A JavaScript runtime (Browser or Node.js) includes:
- Call Stack
- Heap (Memory)
- Web APIs / Node APIs
- Macrotask Queue (Task Queue)
- Microtask Queue
- Event Loop
High-level flow:
JS Code → Call Stack → (async APIs) → Microtasks / Macrotasks ↑ Event LoopThe Event Loop checks:
“Is the call stack empty?”
If yes → pushes the next task.
3. Synchronous vs Asynchronous Execution
Synchronous
Runs immediately on the call stack:
console.log("A");console.log("B");Output:
ABAsynchronous
offloaded to the environment:
setTimeout(() => console.log("C"), 0);console.log("D");Output:
DC4. Macrotasks vs Microtasks
JavaScript has two task queues.
4.1 Macrotasks
Examples:
setTimeoutsetInterval- DOM events
- I/O callbacks
- setImmediate (Node.js)
- MessageChannel
4.2 Microtasks
Examples:
Promise.then()async/awaitqueueMicrotask()- MutationObserver
Execution Order
- Execute one macrotask
- Execute all microtasks
- Re-render (browser)
- Repeat
5. The Golden Rule
Promise callbacks run before setTimeout callbacks.
Example:
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");Output:
ADCBBecause:
- Microtasks (Promise) run before macrotasks (setTimeout)
6. queueMicrotask()
queueMicrotask() forces a function into the microtask queue.
queueMicrotask(() => console.log("M"));setTimeout(() => console.log("T"), 0);console.log("S");Output:
SMTUsed heavily in custom Promise implementations.
7. Browser vs Node.js Event Loop
Browser Event Loop
- After each macrotask → run all microtasks → re-render UI
Node.js Event Loop (libuv)
Node runs tasks in 6 phases:
- Timers → setTimeout, setInterval
- Pending Callbacks
- Idle/Prepare
- Poll → I/O events
- Check → setImmediate
- Close Callbacks
Microtasks run:
- After each callback
- Between phases
Ordering Example (Node.js)
setTimeout(() => console.log("timeout"));setImmediate(() => console.log("immediate"));May output either:
immediatetimeoutor the opposite.
Inside I/O:
fs.readFile("file.txt", () => { setTimeout(() => console.log("timeout")); setImmediate(() => console.log("immediate"));});Always outputs:
immediatetimeout8. Visual Diagram
┌───────────────────────────┐ │ Call Stack │ └─────────────┬─────────────┘ │ ↓ ┌───────────────────────────┐ │ Web/Node APIs │ └─────────────┬─────────────┘ │ ┌───────┴────────┐ ↓ ↓┌────────────┐ ┌──────────────┐│ Microtasks │ │ Macrotasks │└────────────┘ └──────────────┘ ↑ │ └───────┬────────┘ ↓ ┌──────────────┐ │ Event Loop │ └──────────────┘9. async/await and the Event Loop
async/await uses Promises under the hood.
async function run() { console.log("1"); await null; console.log("2");}run();console.log("3");Output:
13time micro tasks -> 2Because await schedules a microtask.
10. Why UI Freezes (Browser)
while (true) {} // Infinite loopThe event loop never becomes free to process:
- Clicks
- Scroll events
- Rendering
Thus the browser “hangs”.
11. Event Loop Interview Tips
- Mention single-threaded JS
- Explain microtasks vs macrotasks
- Promise → microtask
- setTimeout → macrotask
- Node.js has 6 phases
- Browser renders after microtasks
Common interview trick:
Why does Promise resolve run before setTimeout?
Answer:
Because microtasks always run before the next macrotask.
12. Final Summary
| Concept | Meaning |
|---|---|
| Event Loop | Controls async execution |
| Microtasks | Higher priority (Promises) |
| Macrotasks | Lower priority (Timers, I/O) |
| Browser Loop | Microtasks → render → next task |
| Node Loop | 6-phase libuv loop |