The Event Loop in Node.js is a core part of its non-blocking, asynchronous architecture. It allows Node.js to handle many concurrent operations without creating a new thread for each request. This is possible because of its single-threaded nature combined with an event-driven, non-blocking I/O model.
How the Event Loop Works in Node.js
Timers Phase: Executes callbacks scheduled by setTimeout()
and setInterval()
.
Pending Callbacks Phase: Executes I/O callbacks deferred by the operating system.
Idle, Prepare Phase: Internal operations for the event loop (mostly for Node.js internals).
Poll Phase: Retrieves new I/O events, executes I/O callbacks, and handles other low-level tasks.
Check Phase: Executes setImmediate()
callbacks.
Close Callbacks Phase: Executes callbacks like socket.on('close')
Event Loop Example in Node.js
console.log("1. Start");
// Set a timeout (Timers Phase)
setTimeout(() => {
console.log("4. Timeout (setTimeout)");
}, 0);
// Set an immediate (Check Phase)
setImmediate(() => {
console.log("5. Immediate (setImmediate)");
});
// Simulate I/O operation (Poll Phase)
require("fs").readFile(__filename, () => {
console.log("6. I/O callback (fs.readFile)");
// Nested immediate to demonstrate event loop phases
setImmediate(() => {
console.log("7. Nested Immediate");
});
// Nested timeout to demonstrate event loop phases
setTimeout(() => {
console.log("8. Nested Timeout");
}, 0);
});
console.log("2. End");
Expected Output:
- Start
- End
- Timeout (setTimeout)
- Immediate (setImmediate)
- I/O callback (fs.readFile)
- Nested Immediate
- Nested Timeout
Explanation
Start and End: The synchronous code runs first.
Timers (setTimeout
) are executed after the current operation completes.
Immediate (setImmediate
) callbacks are placed in the check phase, which runs after the poll phase.
I/O Callbacks are executed once the file is read, during the poll phase.
Nested Immediates are prioritized over nested timeouts within the same I/O callback.