Mis à jour le mardi 2 janvier 2018
  • 10 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Les évènements

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

Node.js est un environnement de développement JavaScript basé sur les évènements. Je vous ai montré dans le premier chapitre ce que ça signifie : il y a un seul thread mais aucune opération n'est bloquante. Ainsi, les opérations un peu longues (chargement d'un fichier, téléchargement d'une page web, démarrage d'un serveur web...) sont lancées en tâche de fond et une fonction de callback est appelée quand l'opération est terminée.

Le modèle non bloquant en programmation
Le modèle non bloquant en programmation

Les évènements sont à la base de Node.js. C'est ce qui fait que Node.js est puissant mais aussi un peu plus difficile à appréhender, puisque ça nous impose de coder avec beaucoup de fonctions de callback.

Je vous propose de rentrer ici dans les détails du fonctionnement des évènements Node.js. Nous verrons en particulier comment on peut écouter et créer des évènements. Tout développeur Node.js qui se respecte doit savoir faire ça, alors au boulot ! :D

Ecouter des évènements

Surprise ! Vous savez déjà écouter des évènements en JavaScript. Allons, vous n'allez pas me faire croire que vous n'avez jamais utilisé une bibliothèque comme jQuery pour écouter des évènements sur votre page web !

Par exemple :

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

Avec ce genre d'instruction, vous demandez à exécuter une fonction de callback quand la souris sort d'un élément <canvas> de la page. On dit que vous attachez l'évènement au DOM de la page.

Avec Node.js, le principe est exactement le même. Un très très grand nombre d'objets Node.js émettent des évènements. Leur particularité ? lls héritent tous d'un objet EventEmitter fourni par Node.

Prenons par exemple le module "http" que nous avons utilisé pour créer notre serveur web. Il comprend un objet Server qui émet des évènements d'après la doc :

La doc de Node.js indique les évènements que les objets émettent
La doc de Node.js indique les évènements que les objets émettent

Comment écouter ces évènements ? Supposons par exemple qu'on souhaite écouter l'évènement "close" qui survient quand le serveur est arrêté. Il suffit de faire appel à la méthode on() et d'indiquer :

  • Le nom de l'évènement que vous écoutez (ici "close")

  • La fonction de callback à appeler quand l'évènement survient

Exemple :

server.on('close', function() {
    // Faire quelque chose quand le serveur est arrêté
})

Je vous propose un exemple concret et complet. On va lancer un serveur et l'arrêter juste après. On écoute l'évènement close qui survient lorsque le serveur est arrêté. On affiche un message dans la console quand le serveur s'apprête à s'arrêter.

var http = require('http');

var server = http.createServer(function(req, res) {
  res.writeHead(200);
  res.end('Salut tout le monde !');
});

server.on('close', function() { // On écoute l'évènement close
    console.log('Bye bye !');
})

server.listen(8080); // Démarre le serveur

server.close(); // Arrête le serveur. Déclenche l'évènement close

Mais au fait... createServer() comprend une fonction de callback lui aussi. Pourquoi on n'utilise pas on() ici ?

Bien vu ! En fait, c'est une contraction de code. Lisez la doc de createServer() : elle dit que la fonction de callback qu'on lui envoie en paramètre est automatiquement ajoutée à l'évènement "request" !

Donc ce code :

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

... peut être réécrit comme ceci de façon plus détaillée :

// Code équivalent au précédent
var server = http.createServer();
server.on('request', function(req, res) { });

Bref, les évènements sont partout, vous ne pouvez pas y échapper ! :D
Certains sont simplement un peu "masqués" comme c'est le cas ici, mais il est important de savoir ce qui se passe derrière.

Emettre des évènements

Si vous voulez émettre des évènements vous aussi, c'est très simple : incluez le module EventEmitter et créez un objet basé sur EventEmitter.

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

var jeu = new EventEmitter();

Ensuite, pour émettre un évènement dans votre code, il suffit de faire appel à emit() depuis votre objet basé sur EventEmitter. Indiquez :

  • Le nom de l'évènement que vous voulez générer (ex : "gameover"). A vous de le choisir.

  • Un ou plusieurs éventuels paramètres à passer (facultatif)

Ici, je génère un évènement "gameover" et j'envoie un message à celui qui réceptionnera l'évènement via un paramètre :

jeu.emit('gameover', 'Vous avez perdu !');

Celui qui veut écouter l'évènement doit faire ensuite :

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

Voici un code complet pour tester l'émission d'évènements :

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

var jeu = new EventEmitter();

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

jeu.emit('gameover', 'Vous avez perdu !');

Bon, j'admets, c'est un peu trop simple. Ce code se contente d'émettre un évènement. Dans la réalité, les évènements seront émis depuis des fonctions imbriquées dans d'autres fonctions, et c'est de là que Node.js tire toute sa richesse.

En tout cas comme vous le voyez, le principe n'est pas franchement compliqué à comprendre ! :)

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