Node.js – Event Loops

Event Loops in Node

In the previous lesson, we talked about Callbacks. Now, we would learn of something a bit similar. That is Event Loops.

Event loops and callbacks are features used by Node.js to support concurrency. This is because Node.js is single-threaded application.

 

Events in Node.js

Node.js is an event-driven program. This means that the main program loops listens for events to occurs. Then when an event occurs, a callback is triggered. Already, you know that callbacks are functions that are called when an event is detects.

This is what is also called the observer pattern.

This means that a loop (event loop) is maintained which keeps listening(observing) for events. This is exactly what happens in event-driven programs. This make sense too because, throughout the life of a program, events keep occurring. Hence the name event loop. This is illustrated in the figure 1 below:

 

Event Loop in Node.js

Figure 1: Event Loop in Node.js

 

Events vs Callbacks

As you know, a callback fires when an asynchronous function returns data.For instance, the readFile() function is an async functions that returns the content of a file. In this case it is callback.The code is given below

var fs = require("fs")
var path = "D:/nodefiles/testinput.txt";
fs.readFile(path, function(err, data){ 
   //perform some action
});

 

However, in the case of event, the function (observer) listens for events to occur. Then when an even occurs, then the event listener executes. In Node.js, there are many in-built events. You can find them in the events module and EventEmitter class. Both are used to bind events to event-listeners.

An example of event is file open. So we can have a listener that listens to file-open event. And when it detects it, it fires an event listener.

var fs = require('fs');
var path = 'D:/nodefiles/testinput.txt';
var rs = fs.createReadStream(path);
rs.on('open', function () {
  console.log('A file have been opened');
});

 

Let’s now write another program that uses a complete event loop. The program is as given below;

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Import the events module
var events = require("events");

//Create an eventEmitter variable
var eventEmitter = new events.EventEmitter();

// Create and eventHandler function
var connectHandler = function connected() {
    console.log("connection succeeded");

    //Then fire the data_recieved event as follows
    eventEmitter.emit("data_received");
}

// Bind the connection even with the connectHandler
eventEmitter.on("connection", connectHandler);

// Bind the data_recieved event with a function
eventEmitter.on("data_received", function(){
    console.log("Data was received!");
});

// Now let's fire the connection event
eventEmitter.emit("connection");

console.log("End of Program");

Listing 1 – Event Loop

 

Explaining Listing 1

Let’s try to understand what is happening in Listing 1. I have added line numbers to simplify the explanation.

In line 24, we fired the connection event. This calls the connectHandler in lines 7 to 13.

The connectHandler fires data_recieved event. This calls the data_recieved handler function in line 19. This is an anonymous function.

Also note that in lines 16 and 19, we how how the events are bound to the corresponding eventListeners (handlers).

 

I save this file as events2.js. The output is shown below:

 

Event Emitter Output in Node

 

I would recommend you watch the video to get a clearer understanding.