How well do you know Event Loop?
How well do you know Event Loop?
To understand Event Loop you should know the event-driven programming paradigm. The event-driven programming paradigm means programming control flow determined by the event or change in the state. In perspective of the NodeJS, it listens to events and calls a callback function once the event gets triggered.
NodeJS is single threaded:
Yes, you heard it right NodeJS is single-threaded and non-blocking event-driven but with background workers.
NodeJS server continuously listens on the specified port. When it receives a client request then it will be immediately published to the thread pool and server will be again available to listen to the upcoming request. Like this, all incoming requests will be published to the thread pool. Event loop handles which events to pick from the event queue and assign it to the thread present in the thread pool which will execute the event and will be available for the upcoming request.
When NodeJS starts it initializes event loop, processes the provided input script and it may make async API calls, schedule timers, or call process.nextTick(), then begins processing the event loop.
There are six phases in the event loop. Each box represents one phase and all phases are executed in the order mentioned in the above diagram. Each phase has FIFO queue of callbacks to execute which executes callback specific to a particular phase. When the event loop enters in the specific phase then it executes callbacks of that phase until all callbacks get executed or a maximum number of callbacks get executed. After that, it goes to the next phase to execute remaining callbacks and so on.
Timers: This phase executes callback scheduled by the setTimeout() and setInterval().
Pending callbacks: Executes I/O callbacks deferred to the next iteration loop.
Idle, prepare: Used internally
Poll: Retrieve new I/O operations, execute I/O callbacks (except timers and setImmediate callbacks)
Check: setImmediate() callbacks get executed here.
Close: some close callbacks, like socket.on (‘close’, …)
Phases in detail:
Timers specifies threshold after which callbacks get executed, once that time has passed this callback will get executed on top priority. It is not ensured that callback will get executed at the exact specified time instead it gets executed in the next iteration phase. For example, if we have I/O operation in the setTimeout(…, 100) and that I/O operation took 95ms to execute and 10ms to execute it’s callback so overall polling phase took 105ms to execute I/O operation then only it will execute timer.
This phase executes some system operations callbacks like TCP errors.
This phase handles how long it should block and poll I/O events and then executes event queue. When event loop enters into this phase then it will check if the poll queue is empty or not, if not then it will execute all events in the queue synchronously until all events get executed or a maximum number of events get executed. If the poll queue is empty then it will check for setImmediate callback and executes it immediately if present else it waits for the callbacks to be added in the queue. Once the poll queue is empty it will check for timers whose time threshold has been reached and it will be moved to the timers phase.
This phase will be executed once the Poll phase completed or become idle.
If socket or handle closed abruptly then this close callback will get executed.