Node.js EventEmitter
Toutes les opérations d'E/S asynchrones dans Node.js envoient un événement à la file d'attente d'événements lorsqu'elles se terminent.
De nombreux objets dans Node.js déclenchent des événements : un objet net.Server émet un événement chaque fois qu'une nouvelle connexion est établie, et un objet fs.readStream émet un événement lorsqu'un fichier est ouvert. Tous ces objets qui produisent des événements sont des instances de events.EventEmitter.
EventEmitter est un module principal de Node.js utilisé pour créer, enregistrer et déclencher des événements.
EventEmitter est la base de la programmation événementielle et aide les développeurs à mettre facilement en œuvre des mécanismes de publication et d'abonnement aux événements.
Classe EventEmitter
Le module events ne fournit qu'un seul objet : events.EventEmitter.
Le cœur d'EventEmitter réside dans l'encapsulation des fonctionnalités de déclenchement d'événements et d'écoute d'événements.
Vous pouvez utiliserrequire("events");pour accéder à ce module.
Exemple
var events = require('events');
// Créer un objet eventEmitter
var eventEmitter = new events.EventEmitter();
Si une erreur se produit lors de l'instanciation d'un objet EventEmitter, l'événement error est émis. L'événement newListener est émis lorsqu'un nouvel écouteur est ajouté, et l'événement removeListener est émis lorsqu'un écouteur est supprimé.
Ci-dessous, nous utilisons un exemple simple pour illustrer l'utilisation d'EventEmitter :
Exemple
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
event.on('some_event', function() {
console.log('some_event event triggered');
});
setTimeout(function() {
event.emit('some_event');
}, 1000);
Après avoir exécuté ce code, la console affiche ce qui suit après 1 seconde :some_event event triggeredLe principe est que l'objet event enregistre un écouteur pour l'événement some_event. Ensuite, après 1000 millisecondes, nous envoyons l'événement some_event à l'objet event via setTimeout, à ce moment-là, l'écouteur some_event est appelé.
Le résultat de l'exécution est le suivant :
$ node event.js some_event 事件触发
Chaque événement EventEmitter est composé d'un nom d'événement et de plusieurs paramètres. Le nom d'événement est une chaîne qui exprime généralement une signification particulière. Pour chaque événement, EventEmitter prend en charge plusieurs écouteurs d'événements.
Lorsqu'un événement est déclenché, les écouteurs d'événements enregistrés pour cet événement sont appelés dans l'ordre, et les paramètres de l'événement sont transmis en tant qu'arguments de la fonction de rappel.
Expliquons ce processus à l'aide de l'exemple suivant :
Exemple
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 parameter', 'arg2 parameter');
L'exécution du code ci-dessus produit le résultat suivant :
$ node event.js listener1 arg1 参数 arg2 参数 listener2 arg1 参数 arg2 参数
Dans l'exemple ci-dessus, emitter enregistre deux écouteurs d'événement pour l'événement someEvent, puis déclenche l'événement someEvent.
D'après le résultat d'exécution, vous pouvez voir que les deux fonctions de rappel des écouteurs d'événement sont appelées l'une après l'autre. C'est l'utilisation la plus simple d'EventEmitter.
EventEmitter fournit plusieurs propriétés, telles queonetemit。onune fonction pour lier des gestionnaires d'événements,emitet une propriété pour déclencher un événement. Ensuite, examinons de plus près les propriétés d'EventEmitter.
Méthodes
| Non. | Metode & Deskripsi |
|---|---|
| 1 | addListener(event, listener) Ajoute un écouteur pour l'événement spécifié à la fin du tableau d'écouteurs. |
| 2 | on(event, listener) Enregistre un écouteur pour l'événement spécifié, acceptant un événement de type chaîne et une fonction de rappel.
server.on('connection', function (stream) {
console.log('someone connected!');
});
|
| 3 | once(event, listener) Enregistre un écouteur unique pour l'événement spécifié, ce qui signifie que l'écouteur sera déclenché au plus une fois et sera immédiatement supprimé après avoir été déclenché.
server.once('connection', function (stream) {
console.log('Ah, we have our first user!');
});
|
| 4 | removeListener(event, listener) Supprime un écouteur pour l'événement spécifié. L'écouteur doit avoir déjà été enregistré pour cet événement. Il accepte deux paramètres : le premier est le nom de l'événement, et le second est le nom de la fonction de rappel.
var callback = function(stream) {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
|
| 5 | removeAllListeners([event]) Supprime tous les écouteurs pour tous les événements. Si un événement est spécifié, il supprime tous les écouteurs pour l'événement spécifié. |
| 6 | setMaxListeners(n) Par défaut, les EventEmitters émettent un avertissement si vous ajoutez plus de 10 écouteurs. La fonction setMaxListeners est utilisée pour modifier la limite par défaut du nombre d'écouteurs. |
| 7 | listeners(event) Renvoie un tableau d'écouteurs pour l'événement spécifié. |
| 8 | emit(event, [arg1], [arg2], [...]) Exécute chaque écouteur dans l'ordre. Si l'événement a des écouteurs enregistrés, il renvoie true ; sinon, il renvoie false. |
Méthodes de classe
| Non. | Metode & Deskripsi |
|---|---|
| 1 | listenerCount(emitter, event) Renvoie le nombre d'écouteurs pour l'événement spécifié. |
events.EventEmitter.listenerCount(emitter, eventName) //已废弃,不推荐 events.emitter.listenerCount(eventName) //推荐
Enregistrer un écouteur d'événement :
Exemple
const myEmitter = new EventEmitter();
// Enregistrer un écouteur d'événement
myEmitter.on('sayHello', (name) => {
console.log(`Hello, ${name}!`);
});
// Déclencher l’événement
myEmitter.emit('sayHello', 'Alice');
Sortie :
Hello, Alice!
Utilisez once() pour enregistrer un événement à usage unique :
myEmitter.once('init', () => {
console.log('Initialization event occurred');
});
myEmitter.emit('init'); // 打印: Initialization event occurred
myEmitter.emit('init'); // 不会再触发
Des paramètres peuvent être passés lorsqu'un événement est déclenché pour être utilisés par les écouteurs :
Exemple
myEmitter.on('data', (value1, value2) => {
console.log(`Received values: ${value1}, ${value2}`);
});
myEmitter.emit('data', 'Node.js', 'EventEmitter');
// Sortie : Received values: Node.js, EventEmitter
Si l'événement déclenché n'a pas d'écouteur correspondant, EventEmitter lèvera une erreur :
Exemple
console.error('Error event triggered:', err);
});
myEmitter.emit('error', new Error('Something went wrong'));
// Affiche : Error event triggered: Error: Something went wrong
Événements
| Non. | Événement & Description |
|---|---|
| 1 | newListener
Cet événement est déclenché lorsqu'un nouvel écouteur est ajouté. |
| 2 | removeListener
Supprime un écouteur du tableau d'écouteurs spécifié. Notez que cette opération modifiera les indices des écouteurs qui viennent après l'écouteur supprimé. |
Exemple
L'exemple suivant démontre l'application de la classe EventEmitter via l'événement connection.
Créez un fichier main.js avec le code suivant :
Exemple
var eventEmitter = new events.EventEmitter();
// Écouteur #1
var listener1 = function listener1() {
console.log('Écouteur listener1 exécuté.');
}
// Écouteur #2
var listener2 = function listener2() {
console.log('Écouteur listener2 exécuté.');
}
// Lier l'événement connection, la fonction gestionnaire est listener1
eventEmitter.addListener('connection', listener1);
// Lier l'événement connection, la fonction gestionnaire est listener2
eventEmitter.on('connection', listener2);
var eventListeners = eventEmitter.listenerCount('connection');
console.log(eventListeners + " écouteurs sont à l'écoute de l'événement connection.");
// Gérer l'événement connection
eventEmitter.emit('connection');
// Supprimer la fonction listener1 liée
eventEmitter.removeListener('connection', listener1);
console.log("listener1 n'est plus à l'écoute.");
// Déclencher l'événement connection
eventEmitter.emit('connection');
eventListeners = eventEmitter.listenerCount('connection');
console.log(eventListeners + " écouteurs sont à l'écoute de l'événement connection.");
console.log("Exécution du programme terminée.");
Le résultat d'exécution du code ci-dessus est le suivant :
$ node main.js 2 个监听器监听连接事件。 监听器 listener1 执行。 监听器 listener2 执行。 listener1 不再受监听。 监听器 listener2 执行。 1 个监听器监听连接事件。 程序执行完毕。
Événement error
EventEmitter définit un événement spécial, error, qui porte la sémantique d'une erreur. Nous déclenchons généralement l'événement error lorsqu'une exception se produit.
Lorsque error est déclenché, EventEmitter stipule que s'il n'y a pas d'écouteur correspondant, Node.js le traitera comme une exception, quittera le programme et affichera un message d'erreur.
Nous définissons généralement des écouteurs pour les objets susceptibles de déclencher l'événement error afin d'éviter que tout le programme ne plante après qu'une erreur se produit. Par exemple :
var events = require('events');
var emitter = new events.EventEmitter();
emitter.emit('error');
L'erreur suivante s'affichera lors de l'exécution :
node.js:201 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Uncaught, unspecified 'error' event. at EventEmitter.emit (events.js:50:15) at Object.<anonymous> (/home/byvoid/error.js:5:9) at Module._compile (module.js:441:26) at Object..js (module.js:459:10) at Module.load (module.js:348:31) at Function._load (module.js:308:12) at Array.0 (module.js:479:10) at EventEmitter._tickCallback (node.js:192:40)
Héritage de EventEmitter
La plupart du temps, nous n'utilisons pas EventEmitter directement, mais nous en héritons dans des objets. Tous les modules de base qui prennent en charge les réponses aux événements, y compris fs, net et http, sont des sous-classes de EventEmitter.
Pourquoi faisons-nous cela ? Il y a deux raisons :
-
Premièrement, implémenter des événements dans un objet ayant une certaine fonctionnalité concrète est sémantiquement approprié ; l'écoute et l'émission d'événements devraient être des méthodes d'un objet.
-
Deuxièmement, le mécanisme objet de JavaScript est basé sur les prototypes et prend en charge l'héritage multiple partiel. Hériter de EventEmitter ne perturbera pas la relation d'héritage originale de l'objet.
La plupart des modules de base de Node.js (tels que HTTP et le système de fichiers) héritent d'EventEmitter. Vous pouvez créer vos propres classes pour hériter d'EventEmitter.
Exemple
const customEmitter = new MyEmitter();
customEmitter.on('customEvent', () => {
console.log('Custom event fired');
});
customEmitter.emit('customEvent');