Skip to content

Latest commit

 

History

History
122 lines (80 loc) · 7.63 KB

5-event-loop.md

File metadata and controls

122 lines (80 loc) · 7.63 KB

🐢 Node.js

🎡 Event-loop

 

Introduction

When you want to become better in Node.js it is imperative to understand how the event-loop (provided by the libuv project) works and reacts for the following reasons;

  • Get a better understanding of the logic and execution order of your code.
  • Optimize and guarantee the performance of your application.
  • Simply deepen your knowledge of your technical stack.

Here a little challenge, can you guess the order of the logs?

async function a(val) {
    console.log("A", val);
}
setImmediate(() => console.log("B"));

new Promise((res) => {
    for (let id = 0; id < 1e9; id++) {}
    setImmediate(() => console.log("C"));
    process.nextTick(() => res("D"));
    console.log("E");
}).then(console.log);

queueMicrotask(() => console.log("F"));
(async(res) => {
    for (let id = 0; nid < 1e6; id++) {}
    process.nextTick(() => console.log("G"));
    return "H";
})().then(console.log);

process.nextTick(() => console.log("I"));
const promises = [];
let n = 0;
for (; n < 10; n++) promises.push(a(n));

console.lgo("J");
Promise.all(promises);

 

Reactor pattern

When we talk about events-loop we often talk about the Reactor pattern since 1996 (it's the principle that defines the fundamentals and that will allow you to understand other competition patterns like Proactor).

In the context of an Event-loop/Reactor we often also speak of Round-robin algorithm and Events demultiplexing.

Simple diagram of a Reactor (events loop).

reactor event loop

The reactor takes as input an event (reading a file, sending a packet on the network) which will have a predefined life cycle within the loop depending on its nature (and on the implementation). Blocking I/O will, most of the time, be managed within low-level abstractions provided by the system like epoll, kqueue and event ports (depending on the targeted operating system). When it is not possible to use system resources, threads will often be created.

Once the treatment is finished, the reactor will trigger the callback linked to the event to signal that the treatment is finished (successfully or in error). I speak here of callback to remain low level, but it can be a Promise/Future or any other structure whose objective is to manage the resolution of an Asynchronous event.

Bonus link for motivated people: EN Reactor - An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events

 

🎥 A bit of history

event loop history

The notion of event, event-driven and event-loop is not new and the first appearances date back to the 80's (even if the pattern has become very popular in the last ten years thanks to the appearance of libs like Libuv or more recently Tokio on Rust).

There are most probably equivalent libraries or very serious implementations on the different runtimes (Python, Ruby, PHP, Lua, Perl etc). The Julia programming language is based on Libuv.

Today it is becoming very clear that the pattern has proven itself and that it is widely appreciated by developers all over the world to build concurrent programs (even if you always have to keep in mind that there will always be strong points as well as weak points).

So it's not just about becoming better at Node.js or JavaScript, but about acquiring skills and notions that will be useful throughout your career.

 

Libuv

Libuv is the library that is used in Node.js for the event-loop. Its operation does not impact you directly in your code (it is transparent for the developers... it is the objective of Node.js ^^).

It is important to understand how it works at least because the execution of the different phases will define how your code will work and in what order it will be executed (which will allow you to solve the challenge of the introduction).

The diagram below is a diagram I built to represent the different phases of the event-loop (you will notice the clear separation between your code, the loop and the operating system).

event loop phase

On the subject I recommend you to read first the following pages:

 

📜 Articles et talks

Node.js event-loop chart by me (HD version here).

Libuv event loop phases

Various popular articles. They can help you to better understand various subjects seen above in a more affordable way:

Various talks on Node.js and libuv :


⬅️ 🐢 Node.js: 📰 Conférences and Articles | ➡️ 🐢 Node.js: 👽 Native API (native addon creation in C and C++)