The Node.js Event Loop, Timers, and process.nextTick() | Node.js
JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue
The Event Loop is a fundamental part of Node.js architecture. It is a mechanism that enables Node.js to handle I/O operations in a non-blocking way. The Event Loop is a single thread that processes multiple requests using an event-driven architecture.
The event loop is what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible.
Since most modern kernels are multi-threaded, when one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed.
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘
Each phase has a FIFO queue of callbacks to execute. While each phase is special in its own way, generally, when the event loop enters a given phase, it will perform any operations specific to that phase, then execute callbacks in that phase's queue until the queue has been exhausted or the maximum number of callbacks has executed. When the queue has been exhausted or the callback limit is reached, the event loop will move to the next phase, and so on.
setTimeout()
and setInterval()
.setImmediate()
); Node will block here when appropriate.setImmediate()
callbacks are invoked here.socket.on('close', ...)
.Node.js uses a combination of I/O polling and timers to manage the event queue. I/O polling checks for events in the queue, and when none are found, a timer takes over.
The first phase is the timers phase, which executes callbacks scheduled by setTimeout()
and setInterval()
if their threshold time has passed.