Topic 13 of 55
Event Loop
Overview
The event loop is what makes Node.js non-blocking despite being single-threaded. Understanding phases (timers, I/O, setImmediate, nextTick) explains why async operations run in certain orders and helps debug timing issues.
Syntax
javascript
// Event loop phases (simplified):
// 1. timers — setTimeout, setInterval callbacks
// 2. pending I/O — I/O callbacks (file, network)
// 3. idle, prepare — internal
// 4. poll — retrieve new I/O events
// 5. check — setImmediate callbacks
// 6. close — close event callbacks
// Special: process.nextTick — runs BEFORE next phase!
// Special: Promise.then — runs before next tick
// Priority order (highest to lowest):
// process.nextTick > Promise microtasks > setImmediate > setTimeout
process.nextTick(() => console.log("1: nextTick"));
Promise.resolve().then(() => console.log("2: Promise"));
setImmediate(() => console.log("3: setImmediate"));
setTimeout(() => console.log("4: setTimeout"), 0);
// Output: 1, 2, 3, 4 (usually — timers depend on system)Common Pitfalls
- process.nextTick() can starve the event loop if called recursively — it runs all nextTick callbacks before proceeding to the next phase.
- setTimeout(fn, 0) does not mean immediately — it fires as soon as the timer phase runs, which has a minimum ~1ms delay.
- Interview tip: This is the most common Node.js interview topic. The key insight: nextTick > Promises > setImmediate > setTimeout.
Real-World Example
Understanding when operations actually execute
example
javascript
const fs = require("fs");
console.log("1: synchronous start");
setTimeout(() => console.log("2: setTimeout 0"), 0);
setImmediate(() => console.log("3: setImmediate"));
fs.readFile("/tmp/test.txt", () => {
console.log("4: fs.readFile callback");
setTimeout(() => console.log("5: setTimeout in I/O"), 0);
setImmediate(() => console.log("6: setImmediate in I/O")); // runs first!
});
Promise.resolve().then(() => console.log("7: Promise.then"));
process.nextTick(() => console.log("8: nextTick"));
console.log("9: synchronous end");
// Output order: 1, 9, 8, 7, 2, 3, 4, 6, 5