• 15 heures
  • Difficile

Mis à jour le 23/01/2018

Events

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Node.js is an events-based JavaScript development environment. In the first chapter I showed you what that means, i.e. there is only one thread but none of the operations is blocking. This way, longer operations (loading a file, downloading a web page, starting a web server, etc.) are launched in the background and a callback function is called when the operation is complete.

The non-blocking model in programming
The non-blocking model in programming

The events are the base of Node.js. This is what makes Node.js powerful but also a little more difficult to grasp because it forces us to code with lots of callback functions.

Here, we are going to look into the details of how Node.js functions work. We will see, in particular, how we can listen to and create events. Any self-respecting Node.js developer should know how to do it, so let’s get to work! :D

Listening to events

Surprise! You already know how to listen to events in JavaScript. You’re not going to tell me that you’ve never used a library such as jQuery to listen to events on your webpage!

For example:

$("canvas").on("mouseleave", function() { ... });

With this kind of instruction, you are asking for a callback function to be run when the mouse leaves an <canvas> element on the page. This is called attaching an event to the page’s DOM.

With Node.js, the principle is exactly the same. A very large number of Node.js objects emit events. Their particularity is that they all inherit from an EventEmitter object provided by Node.

For example, let’s take the http module that we used to create our web server. It includes a Server object that emits events. The figure below is an extract from the online Node.js documentation:

The Node.js documentation shows the events that the objects emit
The Node.js documentation shows the events that the objects emit

How can you listen to these events? Supposing that, for example, we want to listen to the close event that occurs when the server is stopped. You simply need to use the on() method and enter:

  • The name of the event that you are listening to (here it’s "close").

  • The callback function to call when the event occurs.

Example:

server.on('close', function() {
    // Do something when the server is stopped
})

Here’s a real, complete example: we launch the server and then stop it soon after. We’re listening to the close event that occurs when the server is stopped. We display a message in the console when the server is preparing to stop.

var http = require('http');

var server = http.createServer(function(req, res) {
  res.writeHead(200);
  res.end('Hi everybody!');
});

server.on('close', function() { // We listened to the close event
    console.log('Goodbye!');
})

server.listen(8080); // Starts the server

server.close(); // Stops the server. Triggers the close event

But… createServer() contains a callback function too. Why don’t we use on() here?

Well spotted! It’s actually a code contraction. Read the CreateServer section in the documentation shown in the previous web code. It says that the callback function that we send to it as a setting is automatically added to the "request" event!

So this code:

var server = http.createServer(function(req, res) { });

… can be rewritten like this in a more detailed way:

// Equivalent code to the previous one
var server = http.createServer();
server.on('request', function(req, res) { });

In short, events are everywhere, you can’t avoid them! :D
Some are simply slightly "hidden" as in this case, but it’s important to know what’s happening behind it.

Emitting events

If you want to emit events too, it’s very simple, just include the EventEmitter module and create an object based on Event Emitter.

var EventEmitter = require('events').EventEmitter;

var game = new EventEmitter();

Then, to emit an event in your code, you justy need to enter emit() from your object based on EventEmitter. Indicate:

  • The name of the event that you want to manage (ex: "gameover"). It’s your choice.

  • One or several possible settings to pass (optional).

Here, I’m generating a "gameover" event and I’m sending a message to the recipient of the event via a setting:

game.emit('gameover', 'You lose!');

Anyone who wants to listen to the event then needs to do:

game.on('gameover', function(message) { });

Here is a complete code to test the emission of events:

var EventEmitter = require('events').EventEmitter;

var game = new EventEmitter();

game.on('gameover', function(message){
    console.log(message);
});

game.emit('gameover', 'You lose!');

I’ll admit that it’s a little too simple. This code is limited to emitting an event. In reality, events will be emitted from the functions built within other functions – this is where Node.js gets its richness.

As you can see, the principle really isn’t complicated to understand! :)

game.emit('newplayer', 'Mario', 35); // Sends the name of a new player who’s just arrived and gives their age

Summing up

  • All Node.js applications are based on a mechanism of events, which determine which function will be called next.

  • With the on()  method, you can listen to an event and say which function is to be called when the event occurs.

  • With the emit()  method you can create your own event and so cause the triggering of the functions that are waiting for that event.

Exemple de certificat de réussite
Exemple de certificat de réussite