0 XP
?
Intermédiaire35 min25 XP

Objectifs de cette leçon

  • Créer un EventEmitter
  • Enregistrer des listeners avec on()
  • Émettre des événements avec emit()

Événements (EventEmitter) 📡

Le pattern Observer

Node.js est construit autour du pattern événementiel : des objets émettent des événements, et d'autres objets écoutent et réagissent.

C'est comme un système de notifications : tu t'abonnes (on), et quand l'événement se produit, ton callback est appelé automatiquement.


EventEmitter : les bases

import { EventEmitter } from 'node:events';

class Serveur extends EventEmitter {
  demarrer(port) {
    console.log(`Serveur en écoute sur le port ${port}`);
    this.emit('demarre', { port, date: new Date() });
  }
}

const serveur = new Serveur();

// S'abonner à un événement
serveur.on('demarre', (data) => {
  console.log(`Serveur démarré sur le port ${data.port}`);
});

// Émettre l'événement
serveur.demarrer(3000);
// Serveur en écoute sur le port 3000
// Serveur démarré sur le port 3000

Méthodes principales

MéthodeDescription
emitter.on(event, fn)Écouter un événement
emitter.emit(event, ...args)Émettre un événement
emitter.once(event, fn)Écouter une seule fois
emitter.off(event, fn)Se désabonner

Exemple : Bus événementiel

import { EventEmitter } from 'node:events';

const bus = new EventEmitter();

// Écouteurs
bus.on('message', (msg) => console.log(`📩 ${msg}`));
bus.on('erreur', (err) => console.error(`❌ ${err.message}`));
bus.once('ready', () => console.log('✅ Prêt !'));

// Émettre des événements
bus.emit('message', 'Nouvel utilisateur');
bus.emit('message', 'Commande reçue');
bus.emit('ready');
bus.emit('ready'); // Ignoré (once = une seule fois)
bus.emit('erreur', new Error('Connexion perdue'));

Gestion d'erreurs avec events

import { EventEmitter } from 'node:events';

const emitter = new EventEmitter();

emitter.on('error', (err) => {
  console.error('Erreur capturée :', err.message);
});

// Ajouter un piège pour les erreurs non capturées
process.on('uncaughtException', (err) => {
  console.error('Exception non capturée :', err);
  process.exit(1);
});

💡 Sans écouteur error, les erreurs non capturées font planter le processus.


Streams et événements

Les streams (flux) en Node.js sont des EventEmitters :

import fs from 'node:fs';

const stream = fs.createReadStream('gros-fichier.txt', {
  encoding: 'utf-8',
  highWaterMark: 64 * 1024 // 64 Ko par chunk
});

stream.on('data', (chunk) => {
  console.log(`Chunk reçu : ${chunk.length} caractères`);
});

stream.on('end', () => {
  console.log('Lecture terminée');
});

stream.on('error', (err) => {
  console.error('Erreur de lecture :', err.message);
});

Patterns pratiques

Écouteur dynamique

class Gestionnaire extends EventEmitter {
  constructor() {
    super();
    this.compteurs = {};
  }

  on(event, fn) {
    this.compteurs[event] = (this.compteurs[event] || 0) + 1;
    return super.on(event, fn);
  }

  getStats() {
    return { ...this.compteurs };
  }
}

Résumé

ConceptDescription
EventEmitterClasse de base des événements
.on()S'abonner à un événement
.emit()Déclencher un événement
.once()S'abonner une seule fois
errorÉvénement spécial pour les erreurs

Exercices 🎯

  1. Crée un Compteur qui émet 'increment' à chaque ajouter() et 'decrement' à chaque enlever()
  2. Crée un PingPong qui alterne entre les événements ping et pong avec un délai de 1 seconde
  3. Utilise un Readable Stream pour lire un gros fichier et compter le nombre de lignes

⚡ Simulateur — Événements

Étape 1/4
📝 Pseudo-code
1const EventEmitter = require("events");
2const emitter = new EventEmitter();
3emitter.on("data", (msg) => console.log(msg));
4emitter.emit("data", "Hello!");
⚙️ Exécution
📦 Mémoire
Aucune variable
🔀 Flux d'exécution
require("events")
3
Import du module events

require("events") importe le module EventEmitter, le système d'événement central de Node.js.