Événements
[Stable: 2 - Stable]
Stable: 2 Stability: 2 - Stable
Code source : lib/events.js
Une grande partie de l’API principale de Node.js est construite autour d’une architecture asynchrone et événementielle idiomatique dans laquelle certains types d’objets (appelés « émetteurs ») émettent des événements nommés qui entraînent l’appel d’objets Function
(« écouteurs »).
Par exemple : un objet net.Server
émet un événement chaque fois qu’un pair s’y connecte ; un fs.ReadStream
émet un événement lorsque le fichier est ouvert ; un flux émet un événement chaque fois que des données sont disponibles pour être lues.
Tous les objets qui émettent des événements sont des instances de la classe EventEmitter
. Ces objets exposent une fonction eventEmitter.on()
qui permet d’attacher une ou plusieurs fonctions aux événements nommés émis par l’objet. En règle générale, les noms d’événements sont des chaînes en camelCase, mais toute clé de propriété JavaScript valide peut être utilisée.
Lorsque l’objet EventEmitter
émet un événement, toutes les fonctions attachées à cet événement spécifique sont appelées synchroniquement. Toutes les valeurs renvoyées par les écouteurs appelés sont ignorées et rejetées.
L’exemple suivant montre une instance simple de EventEmitter
avec un seul écouteur. La méthode eventEmitter.on()
est utilisée pour enregistrer les écouteurs, tandis que la méthode eventEmitter.emit()
est utilisée pour déclencher l’événement.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');
Transmettre des arguments et this
aux écouteurs
La méthode eventEmitter.emit()
permet de transmettre un ensemble arbitraire d’arguments aux fonctions d’écoute. Gardez à l’esprit que lorsqu’une fonction d’écoute ordinaire est appelée, le mot-clé standard this
est intentionnellement défini pour faire référence à l’instance EventEmitter
à laquelle l’écouteur est attaché.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this, this === myEmitter);
// Prints:
// a b MyEmitter {
// _events: [Object: null prototype] { event: [Function (anonymous)] },
// _eventsCount: 1,
// _maxListeners: undefined,
// [Symbol(shapeMode)]: false,
// [Symbol(kCapture)]: false
// } true
});
myEmitter.emit('event', 'a', 'b');
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this, this === myEmitter);
// Prints:
// a b MyEmitter {
// _events: [Object: null prototype] { event: [Function (anonymous)] },
// _eventsCount: 1,
// _maxListeners: undefined,
// [Symbol(shapeMode)]: false,
// [Symbol(kCapture)]: false
// } true
});
myEmitter.emit('event', 'a', 'b');
Il est possible d’utiliser les fonctions fléchées ES6 comme écouteurs, cependant, dans ce cas, le mot-clé this
ne fera plus référence à l’instance EventEmitter
:
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b undefined
});
myEmitter.emit('event', 'a', 'b');
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');
Asynchrone vs. synchrone
L'EventEmitter
appelle tous les écouteurs de manière synchrone dans l'ordre dans lequel ils ont été enregistrés. Cela garantit la bonne séquence des événements et permet d'éviter les conditions de concurrence et les erreurs logiques. Le cas échéant, les fonctions d'écoute peuvent passer à un mode de fonctionnement asynchrone en utilisant les méthodes setImmediate()
ou process.nextTick()
:
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
setImmediate(() => {
console.log('this happens asynchronously');
});
});
myEmitter.emit('event', 'a', 'b');
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
setImmediate(() => {
console.log('this happens asynchronously');
});
});
myEmitter.emit('event', 'a', 'b');
Gérer les événements une seule fois
Lorsqu'un écouteur est enregistré à l'aide de la méthode eventEmitter.on()
, cet écouteur est invoqué chaque fois que l'événement nommé est émis.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2
En utilisant la méthode eventEmitter.once()
, il est possible d'enregistrer un écouteur qui est appelé au plus une fois pour un événement particulier. Une fois l'événement émis, l'écouteur est désenregistré et ensuite appelé.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Ignored
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Ignored
Événements d'erreur
Lorsqu'une erreur se produit dans une instance EventEmitter
, l'action typique est d'émettre un événement 'error'
. Ceux-ci sont traités comme des cas particuliers dans Node.js.
Si un EventEmitter
n'a pas au moins un écouteur enregistré pour l'événement 'error'
, et qu'un événement 'error'
est émis, l'erreur est levée, une trace de pile est imprimée, et le processus Node.js se termine.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Lance une erreur et fait planter Node.js
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Lance une erreur et fait planter Node.js
Pour se prémunir contre le plantage du processus Node.js, le module domain
peut être utilisé. (Notez cependant que le module node:domain
est déprécié.)
En guise de bonne pratique, des écouteurs doivent toujours être ajoutés pour les événements 'error'
.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Affiche : whoops! there was an error
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Affiche : whoops! there was an error
Il est possible de surveiller les événements 'error'
sans consommer l'erreur émise en installant un écouteur à l'aide du symbole events.errorMonitor
.
import { EventEmitter, errorMonitor } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Lance toujours une erreur et fait planter Node.js
const { EventEmitter, errorMonitor } = require('node:events');
const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Lance toujours une erreur et fait planter Node.js
Capture des rejets de promesses
L'utilisation de fonctions async
avec des gestionnaires d'événements est problématique, car elle peut entraîner un rejet non géré en cas d'exception levée :
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
ee.on('something', async (value) => {
throw new Error('kaboom');
});
const EventEmitter = require('node:events');
const ee = new EventEmitter();
ee.on('something', async (value) => {
throw new Error('kaboom');
});
L'option captureRejections
dans le constructeur EventEmitter
ou le paramètre global modifie ce comportement, en installant un gestionnaire .then(undefined, handler)
sur la Promise
. Ce gestionnaire achemine l'exception de manière asynchrone vers la méthode Symbol.for('nodejs.rejection')
s'il y en a une, ou vers le gestionnaire d'événement 'error'
s'il n'y en a pas.
import { EventEmitter } from 'node:events';
const ee1 = new EventEmitter({ captureRejections: true });
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
const ee2 = new EventEmitter({ captureRejections: true });
ee2.on('something', async (value) => {
throw new Error('kaboom');
});
ee2[Symbol.for('nodejs.rejection')] = console.log;
const EventEmitter = require('node:events');
const ee1 = new EventEmitter({ captureRejections: true });
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
const ee2 = new EventEmitter({ captureRejections: true });
ee2.on('something', async (value) => {
throw new Error('kaboom');
});
ee2[Symbol.for('nodejs.rejection')] = console.log;
Définir events.captureRejections = true
modifiera la valeur par défaut pour toutes les nouvelles instances de EventEmitter
.
import { EventEmitter } from 'node:events';
EventEmitter.captureRejections = true;
const ee1 = new EventEmitter();
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
const events = require('node:events');
events.captureRejections = true;
const ee1 = new events.EventEmitter();
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
Les événements 'error'
qui sont générés par le comportement captureRejections
n'ont pas de gestionnaire catch pour éviter les boucles d'erreur infinies : la recommandation est de ne pas utiliser les fonctions async
comme gestionnaires d'événements 'error'
.
Classe : EventEmitter
[Historique]
Version | Modifications |
---|---|
v13.4.0, v12.16.0 | Ajout de l’option captureRejections. |
v0.1.26 | Ajouté dans : v0.1.26 |
La classe EventEmitter
est définie et exposée par le module node:events
:
import { EventEmitter } from 'node:events';
const EventEmitter = require('node:events');
Tous les EventEmitter
émettent l’événement 'newListener'
lorsque de nouveaux auditeurs sont ajoutés et 'removeListener'
lorsque des auditeurs existants sont supprimés.
Elle prend en charge l’option suivante :
captureRejections
<boolean> Elle permet la capture automatique du rejet de promesse. Par défaut :false
.
Événement : 'newListener'
Ajouté dans : v0.1.26
eventName
<string> | <symbol> Le nom de l’événement écoutélistener
<Function> La fonction de gestion d’événements
L’instance EventEmitter
émettra son propre événement 'newListener'
avant qu’un auditeur ne soit ajouté à son tableau interne d’auditeurs.
Les auditeurs enregistrés pour l’événement 'newListener'
reçoivent le nom de l’événement et une référence à l’auditeur en cours d’ajout.
Le fait que l’événement soit déclenché avant d’ajouter l’auditeur a un effet secondaire subtil mais important : tout auditeur supplémentaire enregistré pour le même name
dans le rappel 'newListener'
est inséré avant l’auditeur en cours d’ajout.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// À faire une seule fois pour ne pas boucler indéfiniment
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insérer un nouvel auditeur devant
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Affiche :
// B
// A
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// À faire une seule fois pour ne pas boucler indéfiniment
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insérer un nouvel auditeur devant
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Affiche :
// B
// A
Événement : 'removeListener'
[Historique]
Version | Modifications |
---|---|
v6.1.0, v4.7.0 | Pour les écouteurs attachés en utilisant .once() , l'argument listener renvoie maintenant la fonction d'écoute d'origine. |
v0.9.3 | Ajouté dans : v0.9.3 |
eventName
<string> | <symbol> Le nom de l’événement.listener
<Function> La fonction de gestionnaire d’événements.
L'événement 'removeListener'
est émis après que le listener
est supprimé.
emitter.addListener(eventName, listener)
Ajouté dans : v0.1.26
eventName
<string> | <symbol>listener
<Function>
Alias pour emitter.on(eventName, listener)
.
emitter.emit(eventName[, ...args])
Ajouté dans : v0.1.26
Appelle de manière synchrone chacun des écouteurs enregistrés pour l’événement nommé eventName
, dans l’ordre dans lequel ils ont été enregistrés, en transmettant les arguments fournis à chacun.
Retourne true
si l’événement avait des écouteurs, false
sinon.
import { EventEmitter } from 'node:events';
const myEmitter = new EventEmitter();
// Premier écouteur
myEmitter.on('event', function firstListener() {
console.log('Helloooo ! premier écouteur');
});
// Deuxième écouteur
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`événement avec les paramètres ${arg1}, ${arg2} dans le deuxième écouteur`);
});
// Troisième écouteur
myEmitter.on('event', function thirdListener(...args) {
const parameters = args.join(', ');
console.log(`événement avec les paramètres ${parameters} dans le troisième écouteur`);
});
console.log(myEmitter.listeners('event'));
myEmitter.emit('event', 1, 2, 3, 4, 5);
// Prints:
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Helloooo! premier écouteur
// événement avec les paramètres 1, 2 dans le deuxième écouteur
// événement avec les paramètres 1, 2, 3, 4, 5 dans le troisième écouteur
const EventEmitter = require('node:events');
const myEmitter = new EventEmitter();
// Premier écouteur
myEmitter.on('event', function firstListener() {
console.log('Helloooo ! premier écouteur');
});
// Deuxième écouteur
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`événement avec les paramètres ${arg1}, ${arg2} dans le deuxième écouteur`);
});
// Troisième écouteur
myEmitter.on('event', function thirdListener(...args) {
const parameters = args.join(', ');
console.log(`événement avec les paramètres ${parameters} dans le troisième écouteur`);
});
console.log(myEmitter.listeners('event'));
myEmitter.emit('event', 1, 2, 3, 4, 5);
// Prints:
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Helloooo! premier écouteur
// événement avec les paramètres 1, 2 dans le deuxième écouteur
// événement avec les paramètres 1, 2, 3, 4, 5 dans le troisième écouteur
emitter.eventNames()
Ajoutée dans : v6.0.0
- Retourne : <Array>
Retourne un tableau listant les événements pour lesquels l'émetteur a enregistré des auditeurs. Les valeurs du tableau sont des chaînes ou des Symbol
s.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Affiche : [ 'foo', 'bar', Symbol(symbol) ]
const EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Affiche : [ 'foo', 'bar', Symbol(symbol) ]
emitter.getMaxListeners()
Ajoutée dans : v1.0.0
- Retourne : <integer>
Retourne la valeur maximale actuelle de l'auditeur pour l'EventEmitter
qui est soit définie par emitter.setMaxListeners(n)
ou est par défaut events.defaultMaxListeners
.
emitter.listenerCount(eventName[, listener])
[Historique]
Version | Modifications |
---|---|
v19.8.0, v18.16.0 | Ajout de l'argument listener . |
v3.2.0 | Ajoutée dans : v3.2.0 |
eventName
<string> | <symbol> : le nom de l’événement écouté.listener
<Function> : la fonction de gestion des événements.- Retourne : <integer>
Retourne le nombre d’auditeurs qui écoutent l’événement nommé eventName
. Si listener
est fourni, il renverra le nombre de fois où l’auditeur est trouvé dans la liste des auditeurs de l’événement.
emitter.listeners(eventName)
[Historique]
Version | Modifications |
---|---|
v7.0.0 | Pour les listeners attachés en utilisant .once() , cela renvoie maintenant les listeners originaux au lieu des fonctions wrapper. |
v0.1.26 | Ajouté dans : v0.1.26 |
eventName
<string> | <symbol>- Retourne : <Function[]>
Retourne une copie du tableau des listeners pour l'événement nommé eventName
.
server.on('connection', (stream) => {
console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
// Prints: [ [Function] ]
emitter.off(eventName, listener)
Ajouté dans : v10.0.0
eventName
<string> | <symbol>listener
<Function>- Retourne : <EventEmitter>
Alias de emitter.removeListener()
.
emitter.on(eventName, listener)
Ajouté dans : v0.1.101
eventName
<string> | <symbol> Le nom de l'événement.listener
<Function> La fonction de callback- Retourne : <EventEmitter>
Ajoute la fonction listener
à la fin du tableau des listeners pour l'événement nommé eventName
. Aucune vérification n'est effectuée pour voir si le listener
a déjà été ajouté. Plusieurs appels passant la même combinaison de eventName
et listener
entraîneront l'ajout et l'appel du listener
plusieurs fois.
server.on('connection', (stream) => {
console.log('someone connected!');
});
Retourne une référence à EventEmitter
, afin que les appels puissent être chaînés.
Par défaut, les listeners d'événements sont invoqués dans l'ordre dans lequel ils sont ajoutés. La méthode emitter.prependListener()
peut être utilisée comme alternative pour ajouter le listener d'événements au début du tableau des listeners.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
const EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
emitter.once(eventName, listener)
Ajouté dans : v0.3.0
eventName
<string> | <symbol> Le nom de l'événement.listener
<Function> La fonction de rappel- Retourne : <EventEmitter>
Ajoute une fonction listener
à exécution unique pour l'événement nommé eventName
. La prochaine fois que eventName
est déclenché, ce listener est supprimé puis invoqué.
server.once('connection', (stream) => {
console.log('Ah, nous avons notre premier utilisateur !');
});
Retourne une référence à l' EventEmitter
, afin que les appels puissent être chaînés.
Par défaut, les listeners d'événements sont invoqués dans l'ordre dans lequel ils sont ajoutés. La méthode emitter.prependOnceListener()
peut être utilisée comme alternative pour ajouter le listener d'événement au début du tableau des listeners.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
const EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
emitter.prependListener(eventName, listener)
Ajouté dans : v6.0.0
eventName
<string> | <symbol> Le nom de l'événement.listener
<Function> La fonction de rappel- Retourne : <EventEmitter>
Ajoute la fonction listener
au début du tableau des listeners pour l'événement nommé eventName
. Aucune vérification n'est effectuée pour voir si le listener
a déjà été ajouté. Plusieurs appels passant la même combinaison de eventName
et listener
entraîneront l'ajout et l'appel du listener
plusieurs fois.
server.prependListener('connection', (stream) => {
console.log('quelqu'un s'est connecté !');
});
Retourne une référence à l' EventEmitter
, afin que les appels puissent être chaînés.
emitter.prependOnceListener(eventName, listener)
Ajouté dans: v6.0.0
eventName
<string> | <symbol> Le nom de l’événement.listener
<Function> La fonction de rappel- Retourne : <EventEmitter>
Ajoute une fonction listener
à usage unique pour l’événement nommé eventName
au début du tableau des auditeurs. La prochaine fois que eventName
est déclenché, cet auditeur est supprimé, puis invoqué.
server.prependOnceListener('connection', (stream) => {
console.log('Ah, we have our first user!');
});
Retourne une référence à l’EventEmitter
, afin que les appels puissent être chaînés.
emitter.removeAllListeners([eventName])
Ajouté dans: v0.1.26
eventName
<string> | <symbol>- Retourne : <EventEmitter>
Supprime tous les auditeurs, ou ceux de l’eventName
spécifié.
C’est une mauvaise pratique de supprimer des auditeurs ajoutés ailleurs dans le code, en particulier lorsque l’instance EventEmitter
a été créée par un autre composant ou module (par exemple, les sockets ou les flux de fichiers).
Retourne une référence à l’EventEmitter
, afin que les appels puissent être chaînés.
emitter.removeListener(eventName, listener)
Ajouté dans: v0.1.26
eventName
<string> | <symbol>listener
<Function>- Retourne : <EventEmitter>
Supprime le listener
spécifié du tableau des auditeurs pour l’événement nommé eventName
.
const callback = (stream) => {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
removeListener()
supprimera, au maximum, une instance d’un auditeur du tableau d’auditeurs. Si un seul auditeur a été ajouté plusieurs fois au tableau d’auditeurs pour l’eventName
spécifié, alors removeListener()
doit être appelé plusieurs fois pour supprimer chaque instance.
Une fois qu’un événement est émis, tous les auditeurs qui y sont attachés au moment de l’émission sont appelés dans l’ordre. Cela implique que tout appel removeListener()
ou removeAllListeners()
après l’émission et avant que le dernier auditeur ne termine son exécution ne les supprimera pas de emit()
en cours. Les événements suivants se comportent comme prévu.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
const callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA supprime l’auditeur callbackB mais il sera toujours appelé.
// Tableau interne des auditeurs au moment de l’émission [callbackA, callbackB]
myEmitter.emit('event');
// Affiche :
// A
// B
// callbackB est maintenant supprimé.
// Tableau interne des auditeurs [callbackA]
myEmitter.emit('event');
// Affiche :
// A
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
const callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA supprime l’auditeur callbackB mais il sera toujours appelé.
// Tableau interne des auditeurs au moment de l’émission [callbackA, callbackB]
myEmitter.emit('event');
// Affiche :
// A
// B
// callbackB est maintenant supprimé.
// Tableau interne des auditeurs [callbackA]
myEmitter.emit('event');
// Affiche :
// A
Comme les auditeurs sont gérés à l’aide d’un tableau interne, l’appel de cette fonction modifiera les index de position de tout auditeur enregistré après l’auditeur en cours de suppression. Cela n’aura pas d’incidence sur l’ordre dans lequel les auditeurs sont appelés, mais cela signifie que toutes les copies du tableau d’auditeurs telles que renvoyées par la méthode emitter.listeners()
devront être recréées.
Lorsqu’une seule fonction a été ajoutée en tant que gestionnaire plusieurs fois pour un seul événement (comme dans l’exemple ci-dessous), removeListener()
supprimera l’instance ajoutée le plus récemment. Dans l’exemple, l’auditeur once('ping')
est supprimé :
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
function pong() {
console.log('pong');
}
ee.on('ping', pong);
ee.once('ping', pong);
ee.removeListener('ping', pong);
ee.emit('ping');
ee.emit('ping');
const EventEmitter = require('node:events');
const ee = new EventEmitter();
function pong() {
console.log('pong');
}
ee.on('ping', pong);
ee.once('ping', pong);
ee.removeListener('ping', pong);
ee.emit('ping');
ee.emit('ping');
Retourne une référence à l’EventEmitter
, afin que les appels puissent être chaînés.
emitter.setMaxListeners(n)
Ajouté dans : v0.3.5
n
<integer>- Retourne : <EventEmitter>
Par défaut, les EventEmitter
affichent un avertissement si plus de 10
listeners sont ajoutés pour un événement particulier. Il s'agit d'une valeur par défaut utile qui permet de trouver les fuites de mémoire. La méthode emitter.setMaxListeners()
permet de modifier la limite pour cette instance spécifique de EventEmitter
. La valeur peut être définie sur Infinity
(ou 0
) pour indiquer un nombre illimité de listeners.
Retourne une référence à EventEmitter
, afin que les appels puissent être chaînés.
emitter.rawListeners(eventName)
Ajouté dans : v9.4.0
eventName
<string> | <symbol>- Retourne : <Function[]>
Retourne une copie du tableau des listeners pour l'événement nommé eventName
, y compris tous les wrappers (tels que ceux créés par .once()
).
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();
// Logs "log once" to the console and removes the listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');
// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();
// Logs "log once" to the console and removes the listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');
// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');
emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])
[Historique]
Version | Modifications |
---|---|
v17.4.0, v16.14.0 | N'est plus expérimental. |
v13.4.0, v12.16.0 | Ajoutée dans : v13.4.0, v12.16.0 |
La méthode Symbol.for('nodejs.rejection')
est appelée si un rejet de promesse se produit lors de l'émission d'un événement et que captureRejections
est activé sur l'émetteur. Il est possible d'utiliser events.captureRejectionSymbol
à la place de Symbol.for('nodejs.rejection')
.
import { EventEmitter, captureRejectionSymbol } from 'node:events';
class MyClass extends EventEmitter {
constructor() {
super({ captureRejections: true });
}
[captureRejectionSymbol](err, event, ...args) {
console.log('rejection happened for', event, 'with', err, ...args);
this.destroy(err);
}
destroy(err) {
// Tear the resource down here.
}
}
const { EventEmitter, captureRejectionSymbol } = require('node:events');
class MyClass extends EventEmitter {
constructor() {
super({ captureRejections: true });
}
[captureRejectionSymbol](err, event, ...args) {
console.log('rejection happened for', event, 'with', err, ...args);
this.destroy(err);
}
destroy(err) {
// Tear the resource down here.
}
}
events.defaultMaxListeners
Ajouté dans : v0.11.2
Par défaut, un maximum de 10
auditeurs peuvent être enregistrés pour un même événement. Cette limite peut être modifiée pour des instances EventEmitter
individuelles en utilisant la méthode emitter.setMaxListeners(n)
. Pour modifier la valeur par défaut pour toutes les instances EventEmitter
, la propriété events.defaultMaxListeners
peut être utilisée. Si cette valeur n'est pas un nombre positif, une RangeError
est levée.
Soyez prudent lorsque vous définissez events.defaultMaxListeners
, car la modification affecte toutes les instances EventEmitter
, y compris celles créées avant la modification. Cependant, l'appel de emitter.setMaxListeners(n)
a toujours la priorité sur events.defaultMaxListeners
.
Ce n'est pas une limite stricte. L'instance EventEmitter
autorisera l'ajout d'un plus grand nombre d'auditeurs, mais affichera un avertissement de trace sur stderr indiquant qu'une "possible fuite de mémoire EventEmitter" a été détectée. Pour un seul EventEmitter
, les méthodes emitter.getMaxListeners()
et emitter.setMaxListeners()
peuvent être utilisées pour éviter temporairement cet avertissement :
defaultMaxListeners
n'a aucun effet sur les instances AbortSignal
. Bien qu'il soit toujours possible d'utiliser emitter.setMaxListeners(n)
pour définir une limite d'avertissement pour les instances AbortSignal
individuelles, par défaut les instances AbortSignal
n'avertissent pas.
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
// do stuff
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
// do stuff
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});
L'indicateur de ligne de commande --trace-warnings
peut être utilisé pour afficher la trace de pile de tels avertissements.
L'avertissement émis peut être inspecté avec process.on('warning')
et aura les propriétés supplémentaires emitter
, type
et count
, faisant référence à l'instance de l'émetteur d'événements, au nom de l'événement et au nombre d'auditeurs attachés, respectivement. Sa propriété name
est définie sur 'MaxListenersExceededWarning'
.
events.errorMonitor
Ajouté dans : v13.6.0, v12.17.0
Ce symbole doit être utilisé pour installer un écouteur uniquement pour surveiller les événements 'error'
. Les écouteurs installés à l'aide de ce symbole sont appelés avant que les écouteurs 'error'
réguliers ne soient appelés.
L'installation d'un écouteur à l'aide de ce symbole ne modifie pas le comportement une fois qu'un événement 'error'
est émis. Par conséquent, le processus plantera toujours si aucun écouteur 'error'
régulier n'est installé.
events.getEventListeners(emitterOrTarget, eventName)
Ajouté dans : v15.2.0, v14.17.0
emitterOrTarget
<EventEmitter> | <EventTarget>eventName
<string> | <symbol>- Retourne : <Function[]>
Retourne une copie du tableau des écouteurs pour l'événement nommé eventName
.
Pour les EventEmitter
s, cela se comporte exactement de la même manière que l'appel de .listeners
sur l'émetteur.
Pour les EventTarget
s, c'est la seule façon d'obtenir les écouteurs d'événements pour la cible d'événement. Ceci est utile à des fins de débogage et de diagnostic.
import { getEventListeners, EventEmitter } from 'node:events';
{
const ee = new EventEmitter();
const listener = () => console.log('Events are fun');
ee.on('foo', listener);
console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ]
}
{
const et = new EventTarget();
const listener = () => console.log('Events are fun');
et.addEventListener('foo', listener);
console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ]
}
const { getEventListeners, EventEmitter } = require('node:events');
{
const ee = new EventEmitter();
const listener = () => console.log('Events are fun');
ee.on('foo', listener);
console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ]
}
{
const et = new EventTarget();
const listener = () => console.log('Events are fun');
et.addEventListener('foo', listener);
console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ]
}
events.getMaxListeners(emitterOrTarget)
Ajouté dans : v19.9.0, v18.17.0
emitterOrTarget
<EventEmitter> | <EventTarget>- Retourne : <number>
Retourne le nombre maximum actuel d'écouteurs définis.
Pour les EventEmitter
, cela se comporte exactement de la même manière que l'appel de .getMaxListeners
sur l'émetteur.
Pour les EventTarget
, c'est le seul moyen d'obtenir le nombre maximum d'écouteurs d'événements pour la cible d'événement. Si le nombre de gestionnaires d'événements sur un seul EventTarget dépasse le maximum défini, EventTarget affichera un avertissement.
import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events';
{
const ee = new EventEmitter();
console.log(getMaxListeners(ee)); // 10
setMaxListeners(11, ee);
console.log(getMaxListeners(ee)); // 11
}
{
const et = new EventTarget();
console.log(getMaxListeners(et)); // 10
setMaxListeners(11, et);
console.log(getMaxListeners(et)); // 11
}
const { getMaxListeners, setMaxListeners, EventEmitter } = require('node:events');
{
const ee = new EventEmitter();
console.log(getMaxListeners(ee)); // 10
setMaxListeners(11, ee);
console.log(getMaxListeners(ee)); // 11
}
{
const et = new EventTarget();
console.log(getMaxListeners(et)); // 10
setMaxListeners(11, et);
console.log(getMaxListeners(et)); // 11
}
events.once(emitter, name[, options])
[Historique]
Version | Modifications |
---|---|
v15.0.0 | L'option signal est désormais prise en charge. |
v11.13.0, v10.16.0 | Ajouté dans : v11.13.0, v10.16.0 |
emitter
<EventEmitter>options
<Object>signal
<AbortSignal> Peut être utilisé pour annuler l'attente de l'événement.
Retourne : <Promise>
Crée une Promise
qui est résolue lorsque l'EventEmitter
émet l'événement donné ou qui est rejetée si l'EventEmitter
émet 'error'
pendant l'attente. La Promise
sera résolue avec un tableau de tous les arguments émis à l'événement donné.
Cette méthode est intentionnellement générique et fonctionne avec l'interface EventTarget de la plateforme web, qui n'a pas de sémantique d'événement 'error'
spéciale et n'écoute pas l'événement 'error'
.
import { once, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
process.nextTick(() => {
ee.emit('myevent', 42);
});
const [value] = await once(ee, 'myevent');
console.log(value);
const err = new Error('kaboom');
process.nextTick(() => {
ee.emit('error', err);
});
try {
await once(ee, 'myevent');
} catch (err) {
console.error('error happened', err);
}
const { once, EventEmitter } = require('node:events');
async function run() {
const ee = new EventEmitter();
process.nextTick(() => {
ee.emit('myevent', 42);
});
const [value] = await once(ee, 'myevent');
console.log(value);
const err = new Error('kaboom');
process.nextTick(() => {
ee.emit('error', err);
});
try {
await once(ee, 'myevent');
} catch (err) {
console.error('error happened', err);
}
}
run();
La gestion spéciale de l'événement 'error'
n'est utilisée que lorsque events.once()
est utilisé pour attendre un autre événement. Si events.once()
est utilisé pour attendre l'événement 'error'
lui-même, alors il est traité comme tout autre type d'événement sans gestion spéciale :
import { EventEmitter, once } from 'node:events';
const ee = new EventEmitter();
once(ee, 'error')
.then(([err]) => console.log('ok', err.message))
.catch((err) => console.error('error', err.message));
ee.emit('error', new Error('boom'));
// Prints: ok boom
const { EventEmitter, once } = require('node:events');
const ee = new EventEmitter();
once(ee, 'error')
.then(([err]) => console.log('ok', err.message))
.catch((err) => console.error('error', err.message));
ee.emit('error', new Error('boom'));
// Prints: ok boom
Un <AbortSignal> peut être utilisé pour annuler l'attente de l'événement :
import { EventEmitter, once } from 'node:events';
const ee = new EventEmitter();
const ac = new AbortController();
async function foo(emitter, event, signal) {
try {
await once(emitter, event, { signal });
console.log('event emitted!');
} catch (error) {
if (error.name === 'AbortError') {
console.error('Waiting for the event was canceled!');
} else {
console.error('There was an error', error.message);
}
}
}
foo(ee, 'foo', ac.signal);
ac.abort(); // Prints: Waiting for the event was canceled!
const { EventEmitter, once } = require('node:events');
const ee = new EventEmitter();
const ac = new AbortController();
async function foo(emitter, event, signal) {
try {
await once(emitter, event, { signal });
console.log('event emitted!');
} catch (error) {
if (error.name === 'AbortError') {
console.error('Waiting for the event was canceled!');
} else {
console.error('There was an error', error.message);
}
}
}
foo(ee, 'foo', ac.signal);
ac.abort(); // Prints: Waiting for the event was canceled!
Attendre plusieurs événements émis sur process.nextTick()
Il existe un cas limite à noter lors de l'utilisation de la fonction events.once()
pour attendre plusieurs événements émis dans le même lot d'opérations process.nextTick()
, ou chaque fois que plusieurs événements sont émis de manière synchrone. Plus précisément, étant donné que la file d'attente process.nextTick()
est vidée avant la file d'attente de microtâches Promise
, et que EventEmitter
émet tous les événements de manière synchrone, il est possible que events.once()
manque un événement.
import { EventEmitter, once } from 'node:events';
import process from 'node:process';
const myEE = new EventEmitter();
async function foo() {
await once(myEE, 'bar');
console.log('bar');
// Cette Promise ne sera jamais résolue car l'événement 'foo' aura
// déjà été émis avant la création de la Promise.
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));
const { EventEmitter, once } = require('node:events');
const myEE = new EventEmitter();
async function foo() {
await once(myEE, 'bar');
console.log('bar');
// Cette Promise ne sera jamais résolue car l'événement 'foo' aura
// déjà été émis avant la création de la Promise.
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));
Pour capturer les deux événements, créez chacune des Promises avant d'attendre l'une ou l'autre, puis il devient possible d'utiliser Promise.all()
, Promise.race()
ou Promise.allSettled()
:
import { EventEmitter, once } from 'node:events';
import process from 'node:process';
const myEE = new EventEmitter();
async function foo() {
await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
console.log('foo', 'bar');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));
const { EventEmitter, once } = require('node:events');
const myEE = new EventEmitter();
async function foo() {
await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
console.log('foo', 'bar');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));
events.captureRejections
[Historique]
Version | Modifications |
---|---|
v17.4.0, v16.14.0 | N’est plus expérimental. |
v13.4.0, v12.16.0 | Ajouté dans : v13.4.0, v12.16.0 |
Valeur : <boolean>
Modifie l’option captureRejections
par défaut sur tous les nouveaux objets EventEmitter
.
events.captureRejectionSymbol
[Historique]
Version | Modifications |
---|---|
v17.4.0, v16.14.0 | N’est plus expérimental. |
v13.4.0, v12.16.0 | Ajouté dans : v13.4.0, v12.16.0 |
Valeur : Symbol.for('nodejs.rejection')
Voir comment écrire un gestionnaire de rejet personnalisé.
events.listenerCount(emitter, eventName)
Ajouté dans : v0.9.12
Obsolète depuis : v3.2.0
[Stable: 0 - Obsolète]
Stable: 0 Stability: 0 - Obsolète : Utilisez emitter.listenerCount()
à la place.
emitter
<EventEmitter> L’émetteur à interroger.eventName
<string> | <symbol> Le nom de l’événement.
Une méthode de classe qui renvoie le nombre d’écouteurs pour le eventName
donné enregistré sur le emitter
donné.
import { EventEmitter, listenerCount } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2
const { EventEmitter, listenerCount } = require('node:events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2
events.on(emitter, eventName[, options])
[Historique]
Version | Modifications |
---|---|
v22.0.0, v20.13.0 | Prise en charge des options highWaterMark et lowWaterMark , par souci de cohérence. Les anciennes options sont toujours prises en charge. |
v20.0.0 | Les options close , highWatermark et lowWatermark sont désormais prises en charge. |
v13.6.0, v12.16.0 | Ajoutée dans : v13.6.0, v12.16.0 |
emitter
<EventEmitter>options
<Object>signal
<AbortSignal> Peut être utilisé pour annuler l'attente d'événements.close
- <string[]> Noms des événements qui mettront fin à l'itération.highWaterMark
- <integer> Par défaut :Number.MAX_SAFE_INTEGER
La limite supérieure. L'émetteur est mis en pause chaque fois que la taille des événements mis en mémoire tampon est supérieure à celle-ci. Pris en charge uniquement sur les émetteurs implémentant les méthodespause()
etresume()
.lowWaterMark
- <integer> Par défaut :1
La limite inférieure. L'émetteur est relancé chaque fois que la taille des événements mis en mémoire tampon est inférieure à celle-ci. Pris en charge uniquement sur les émetteurs implémentant les méthodespause()
etresume()
.
Retourne : <AsyncIterator> qui itère sur les événements
eventName
émis par l'emitter
.
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
// Émettre plus tard
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// L'exécution de ce bloc interne est synchrone et il
// traite un événement à la fois (même avec await). Ne pas utiliser
// si une exécution simultanée est requise.
console.log(event); // affiche ['bar'] [42]
}
// Inatteignable ici
const { on, EventEmitter } = require('node:events');
(async () => {
const ee = new EventEmitter();
// Émettre plus tard
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// L'exécution de ce bloc interne est synchrone et il
// traite un événement à la fois (même avec await). Ne pas utiliser
// si une exécution simultanée est requise.
console.log(event); // affiche ['bar'] [42]
}
// Inatteignable ici
})();
Retourne un AsyncIterator
qui itère sur les événements eventName
. Il lèvera une exception si l'EventEmitter
émet 'error'
. Il supprime tous les auditeurs lors de la sortie de la boucle. La value
renvoyée par chaque itération est un tableau composé des arguments d'événement émis.
Un <AbortSignal> peut être utilisé pour annuler l'attente d'événements :
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Émettre plus tard
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// L'exécution de ce bloc interne est synchrone et il
// traite un événement à la fois (même avec await). Ne pas utiliser
// si une exécution simultanée est requise.
console.log(event); // affiche ['bar'] [42]
}
// Inatteignable ici
})();
process.nextTick(() => ac.abort());
const { on, EventEmitter } = require('node:events');
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Émettre plus tard
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// L'exécution de ce bloc interne est synchrone et il
// traite un événement à la fois (même avec await). Ne pas utiliser
// si une exécution simultanée est requise.
console.log(event); // affiche ['bar'] [42]
}
// Inatteignable ici
})();
process.nextTick(() => ac.abort());
events.setMaxListeners(n[, ...eventTargets])
Ajouté dans : v15.4.0
n
<number> Un nombre non négatif. Le nombre maximum d'auditeurs par événementEventTarget
....eventsTargets
<EventTarget[]> | <EventEmitter[]> Zéro instance ou plus de <EventTarget> ou <EventEmitter>. Si aucun n'est spécifié,n
est défini comme maximum par défaut pour tous les objets <EventTarget> et <EventEmitter> nouvellement créés.
import { setMaxListeners, EventEmitter } from 'node:events';
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);
const {
setMaxListeners,
EventEmitter,
} = require('node:events');
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);
events.addAbortListener(signal, listener)
Ajouté dans : v20.5.0, v18.18.0
[Stable: 1 - Experimental]
Stable: 1 Stability: 1 - Expérimental
signal
<AbortSignal>listener
<Function> | <EventListener>- Retourne : <Disposable> Un jetable qui supprime l'écouteur
abort
.
Écoute une fois l'événement abort
sur le signal
fourni.
Écouter l'événement abort
sur les signaux d'abandon n'est pas sûr et peut entraîner des fuites de ressources, car une autre tierce partie avec le signal peut appeler e.stopImmediatePropagation()
. Malheureusement, Node.js ne peut pas changer cela car cela violerait la norme Web. De plus, l'API d'origine permet d'oublier facilement de supprimer les écouteurs.
Cette API permet d'utiliser en toute sécurité les AbortSignal
dans les API Node.js en résolvant ces deux problèmes en écoutant l'événement de sorte que stopImmediatePropagation
n'empêche pas l'écouteur de s'exécuter.
Retourne un jetable afin qu'il puisse être désinscrit plus facilement.
const { addAbortListener } = require('node:events');
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}
import { addAbortListener } from 'node:events';
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}
Classe : events.EventEmitterAsyncResource extends EventEmitter
Ajoutée dans : v17.4.0, v16.14.0
Intègre EventEmitter
avec <AsyncResource> pour les EventEmitter
qui nécessitent un suivi asynchrone manuel. Plus précisément, tous les événements émis par les instances de events.EventEmitterAsyncResource
s’exécuteront dans son contexte asynchrone.
import { EventEmitterAsyncResource, EventEmitter } from 'node:events';
import { notStrictEqual, strictEqual } from 'node:assert';
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
// L’outillage de suivi asynchrone identifiera ceci comme « Q ».
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// Les écouteurs 'foo' s’exécuteront dans le contexte asynchrone des EventEmitters.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// Les écouteurs 'foo' sur les EventEmitters ordinaires qui ne suivent pas
// le contexte asynchrone, s’exécutent toutefois dans le même contexte asynchrone que emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});
const { EventEmitterAsyncResource, EventEmitter } = require('node:events');
const { notStrictEqual, strictEqual } = require('node:assert');
const { executionAsyncId, triggerAsyncId } = require('node:async_hooks');
// L’outillage de suivi asynchrone identifiera ceci comme « Q ».
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// Les écouteurs 'foo' s’exécuteront dans le contexte asynchrone des EventEmitters.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// Les écouteurs 'foo' sur les EventEmitters ordinaires qui ne suivent pas
// le contexte asynchrone, s’exécutent toutefois dans le même contexte asynchrone que emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});
La classe EventEmitterAsyncResource
a les mêmes méthodes et prend les mêmes options que EventEmitter
et AsyncResource
eux-mêmes.
new events.EventEmitterAsyncResource([options])
options
<Object>captureRejections
<boolean> Active la capture automatique des rejets de promesses. Par défaut :false
.name
<string> Le type d'événement asynchrone. Par défaut :new.target.name
.triggerAsyncId
<number> L'ID du contexte d'exécution qui a créé cet événement asynchrone. Par défaut :executionAsyncId()
.requireManualDestroy
<boolean> Si la valeur est définie surtrue
, désactiveemitDestroy
lorsque l'objet est nettoyé par le garbage collector. Il n'est généralement pas nécessaire de définir cette option (même siemitDestroy
est appelé manuellement), sauf siasyncId
de la ressource est récupéré et que l'API sensibleemitDestroy
est appelée avec elle. Lorsque la valeur est définie surfalse
, l'appelemitDestroy
lors du garbage collection n'aura lieu que s'il existe au moins un hookdestroy
actif. Par défaut :false
.
eventemitterasyncresource.asyncId
- Type : <number> L'
asyncId
unique attribué à la ressource.
eventemitterasyncresource.asyncResource
- Type : <AsyncResource> sous-jacent.
L'objet AsyncResource
renvoyé a une propriété eventEmitter
supplémentaire qui fournit une référence à cet EventEmitterAsyncResource
.
eventemitterasyncresource.emitDestroy()
Appelle tous les hooks destroy
. Cela ne doit être appelé qu'une seule fois. Une erreur sera levée s'il est appelé plus d'une fois. Cela doit être appelé manuellement. Si la ressource est laissée à la collecte par le GC, les hooks destroy
ne seront jamais appelés.
eventemitterasyncresource.triggerAsyncId
- Type : <number> Le même
triggerAsyncId
qui est transmis au constructeurAsyncResource
.
API EventTarget
et Event
[Historique]
Version | Modifications |
---|---|
v16.0.0 | Modification de la gestion des erreurs EventTarget. |
v15.4.0 | N'est plus expérimental. |
v15.0.0 | Les classes EventTarget et Event sont maintenant disponibles en tant que globales. |
v14.5.0 | Ajouté dans : v14.5.0 |
Les objets EventTarget
et Event
sont une implémentation spécifique à Node.js de l'API Web EventTarget
qui sont exposés par certaines API centrales de Node.js.
const target = new EventTarget();
target.addEventListener('foo', (event) => {
console.log('l'événement foo s'est produit !');
});
EventTarget
Node.js vs. EventTarget
DOM
Il existe deux différences essentielles entre le EventTarget
Node.js et l'API Web EventTarget
:
NodeEventTarget
vs. EventEmitter
L'objet NodeEventTarget
implémente un sous-ensemble modifié de l'API EventEmitter
qui lui permet d'émuler étroitement un EventEmitter
dans certaines situations. Un NodeEventTarget
n'est pas une instance de EventEmitter
et ne peut pas être utilisé à la place d'un EventEmitter
dans la plupart des cas.
Écouteur d'événements
Les écouteurs d'événements enregistrés pour un type
d'événement peuvent être des fonctions JavaScript ou des objets avec une propriété handleEvent
dont la valeur est une fonction.
Dans les deux cas, la fonction gestionnaire est invoquée avec l'argument event
passé à la fonction eventTarget.dispatchEvent()
.
Les fonctions asynchrones peuvent être utilisées comme écouteurs d'événements. Si une fonction gestionnaire asynchrone rejette, le rejet est capturé et géré comme décrit dans Gestion des erreurs EventTarget
.
Une erreur levée par une fonction gestionnaire n'empêche pas les autres gestionnaires d'être invoqués.
La valeur de retour d'une fonction gestionnaire est ignorée.
Les gestionnaires sont toujours invoqués dans l'ordre dans lequel ils ont été ajoutés.
Les fonctions gestionnaires peuvent modifier l'objet event
.
function handler1(event) {
console.log(event.type); // Affiche 'foo'
event.a = 1;
}
async function handler2(event) {
console.log(event.type); // Affiche 'foo'
console.log(event.a); // Affiche 1
}
const handler3 = {
handleEvent(event) {
console.log(event.type); // Affiche 'foo'
},
};
const handler4 = {
async handleEvent(event) {
console.log(event.type); // Affiche 'foo'
},
};
const target = new EventTarget();
target.addEventListener('foo', handler1);
target.addEventListener('foo', handler2);
target.addEventListener('foo', handler3);
target.addEventListener('foo', handler4, { once: true });
Gestion des erreurs EventTarget
Lorsqu'un écouteur d'événements enregistré lève une exception (ou renvoie une Promise qui est rejetée), par défaut l'erreur est traitée comme une exception non interceptée sur process.nextTick()
. Cela signifie que les exceptions non interceptées dans les EventTarget
mettront fin au processus Node.js par défaut.
Lever une exception dans un écouteur d'événements n'empêchera pas les autres gestionnaires enregistrés d'être invoqués.
L'EventTarget
n'implémente aucune gestion par défaut spéciale pour les événements de type 'error'
comme EventEmitter
.
Actuellement, les erreurs sont d'abord transmises à l'événement process.on('error')
avant d'atteindre process.on('uncaughtException')
. Ce comportement est obsolète et changera dans une future version pour aligner EventTarget
avec d'autres API Node.js. Tout code s'appuyant sur l'événement process.on('error')
doit être aligné sur le nouveau comportement.
Classe : Event
[Historique]
Version | Modifications |
---|---|
v15.0.0 | La classe Event est maintenant disponible via l'objet global. |
v14.5.0 | Ajoutée dans : v14.5.0 |
L'objet Event
est une adaptation de l'API Web Event
. Les instances sont créées en interne par Node.js.
event.bubbles
Ajoutée dans : v14.5.0
- Type : <boolean> Renvoie toujours
false
.
Ceci n'est pas utilisé dans Node.js et est fourni uniquement à des fins d'exhaustivité.
event.cancelBubble
Ajoutée dans : v14.5.0
[Stable: 3 - Legacy]
Stable : 3 Stabilité : 3 - Legacy : utiliser event.stopPropagation()
à la place.
- Type : <boolean>
Alias pour event.stopPropagation()
s'il est défini sur true
. Ceci n'est pas utilisé dans Node.js et est fourni uniquement à des fins d'exhaustivité.
event.cancelable
Ajoutée dans : v14.5.0
- Type : <boolean> Vrai si l'événement a été créé avec l'option
cancelable
.
event.composed
Ajouté dans : v14.5.0
- Type : <boolean> Retourne toujours
false
.
Ceci n'est pas utilisé dans Node.js et est fourni uniquement par souci d'exhaustivité.
event.composedPath()
Ajouté dans : v14.5.0
Retourne un tableau contenant l'EventTarget
actuel comme seule entrée ou vide si l'événement n'est pas en cours de distribution. Ceci n'est pas utilisé dans Node.js et est fourni uniquement par souci d'exhaustivité.
event.currentTarget
Ajouté dans : v14.5.0
- Type : <EventTarget> L'
EventTarget
qui distribue l'événement.
Alias de event.target
.
event.defaultPrevented
Ajouté dans : v14.5.0
- Type : <boolean>
Est true
si cancelable
est true
et que event.preventDefault()
a été appelé.
event.eventPhase
Ajouté dans : v14.5.0
- Type : <number> Retourne
0
lorsqu'un événement n'est pas en cours de distribution,2
lorsqu'il est en cours de distribution.
Ceci n'est pas utilisé dans Node.js et est fourni uniquement par souci d'exhaustivité.
event.initEvent(type[, bubbles[, cancelable]])
Ajouté dans : v19.5.0
[Stable: 3 - Legacy]
Stable: 3 Stabilité : 3 - Hérité : La spécification WHATWG considère qu'il est obsolète et que les utilisateurs ne devraient pas l'utiliser du tout.
Redondant avec les constructeurs d'événements et incapable de définir composed
. Ceci n'est pas utilisé dans Node.js et est fourni uniquement par souci d'exhaustivité.
event.isTrusted
Ajouté dans : v14.5.0
- Type : <boolean>
L'événement abort
de <AbortSignal> est émis avec isTrusted
défini sur true
. La valeur est false
dans tous les autres cas.
event.preventDefault()
Ajouté dans : v14.5.0
Définit la propriété defaultPrevented
sur true
si cancelable
est true
.
event.returnValue
Ajouté dans : v14.5.0
[Stable: 3 - Legacy]
Stable: 3 Stability: 3 - Legacy : Utilisez event.defaultPrevented
à la place.
- Type : <boolean> Vrai si l’événement n’a pas été annulé.
La valeur de event.returnValue
est toujours l’opposé de event.defaultPrevented
. Ceci n’est pas utilisé dans Node.js et est fourni uniquement à titre d’exhaustivité.
event.srcElement
Ajouté dans : v14.5.0
[Stable: 3 - Legacy]
Stable: 3 Stability: 3 - Legacy : Utilisez event.target
à la place.
- Type : <EventTarget> Le
EventTarget
qui déclenche l’événement.
Alias pour event.target
.
event.stopImmediatePropagation()
Ajouté dans : v14.5.0
Arrête l’invocation des écouteurs d’événements après la fin de l’écouteur actuel.
event.stopPropagation()
Ajouté dans : v14.5.0
Ceci n’est pas utilisé dans Node.js et est fourni uniquement à titre d’exhaustivité.
event.target
Ajouté dans : v14.5.0
- Type : <EventTarget> Le
EventTarget
qui déclenche l’événement.
event.timeStamp
Ajouté dans : v14.5.0
- Type : <number>
L’horodatage en millisecondes lors de la création de l’objet Event
.
event.type
Ajouté dans : v14.5.0
- Type : <string>
L’identificateur de type d’événement.
Class: EventTarget
[Historique]
Version | Modifications |
---|---|
v15.0.0 | La classe EventTarget est désormais disponible via l’objet global. |
v14.5.0 | Ajouté dans : v14.5.0 |
eventTarget.addEventListener(type, listener[, options])
[Historique]
Version | Modifications |
---|---|
v15.4.0 | Ajout de la prise en charge de l'option signal . |
v14.5.0 | Ajouté dans : v14.5.0 |
type
<string>listener
<Function> | <EventListener>options
<Object>once
<boolean> Lorsque la valeur esttrue
, l'écouteur est automatiquement supprimé lorsqu'il est invoqué pour la première fois. Par défaut :false
.passive
<boolean> Lorsque la valeur esttrue
, sert d'indice que l'écouteur n'appellera pas la méthodepreventDefault()
de l'objetEvent
. Par défaut :false
.capture
<boolean> Non directement utilisé par Node.js. Ajouté pour l'exhaustivité de l'API. Par défaut :false
.signal
<AbortSignal> L'écouteur sera supprimé lorsque la méthodeabort()
de l'objet AbortSignal donné sera appelée.
Ajoute un nouveau gestionnaire pour l'événement type
. Un listener
donné n'est ajouté qu'une seule fois par type
et par valeur d'option capture
.
Si l'option once
est true
, le listener
est supprimé après la prochaine fois qu'un événement type
est déclenché.
L'option capture
n'est pas utilisée par Node.js d'une manière fonctionnelle autre que le suivi des écouteurs d'événements enregistrés selon la spécification EventTarget
. Plus précisément, l'option capture
est utilisée dans le cadre de la clé lors de l'enregistrement d'un listener
. Un listener
individuel peut être ajouté une fois avec capture = false
et une fois avec capture = true
.
function handler(event) {}
const target = new EventTarget();
target.addEventListener('foo', handler, { capture: true }); // premier
target.addEventListener('foo', handler, { capture: false }); // second
// Supprime la deuxième instance de handler
target.removeEventListener('foo', handler);
// Supprime la première instance de handler
target.removeEventListener('foo', handler, { capture: true });
eventTarget.dispatchEvent(event)
Ajouté dans : v14.5.0
event
<Event>- Renvoie : <boolean>
true
si la valeur de l’attributcancelable
de l’événement est false ou si sa méthodepreventDefault()
n’a pas été appelée, sinonfalse
.
Distribue l’event
à la liste des gestionnaires pour event.type
.
Les écouteurs d’événements enregistrés sont invoqués de manière synchrone dans l’ordre dans lequel ils ont été enregistrés.
eventTarget.removeEventListener(type, listener[, options])
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>options
<Object>capture
<boolean>
Supprime le listener
de la liste des gestionnaires pour l’event
type
.
Class: CustomEvent
[Historique]
Version | Modifications |
---|---|
v23.0.0 | N’est plus expérimental. |
v22.1.0, v20.13.0 | CustomEvent est désormais stable. |
v19.0.0 | N’est plus derrière l’indicateur CLI --experimental-global-customevent . |
v18.7.0, v16.17.0 | Ajouté dans : v18.7.0, v16.17.0 |
[Stable : 2 - Stable]
Stable : 2 Stabilité : 2 - Stable
- Extends: <Event>
L’objet CustomEvent
est une adaptation de l’API Web CustomEvent
. Les instances sont créées en interne par Node.js.
event.detail
[Historique]
Version | Modifications |
---|---|
v22.1.0, v20.13.0 | CustomEvent est désormais stable. |
v18.7.0, v16.17.0 | Ajouté dans : v18.7.0, v16.17.0 |
[Stable : 2 - Stable]
Stable : 2 Stabilité : 2 - Stable
- Type : <any> Renvoie les données personnalisées transmises lors de l’initialisation.
Lecture seule.
Classe : NodeEventTarget
Ajouté dans : v14.5.0
- Hérite de : <EventTarget>
NodeEventTarget
est une extension spécifique à Node.js de EventTarget
qui émule un sous-ensemble de l'API EventEmitter
.
nodeEventTarget.addListener(type, listener)
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>- Retourne : <EventTarget>
this
Extension spécifique à Node.js de la classe EventTarget
qui émule l'API EventEmitter
équivalente. La seule différence entre addListener()
et addEventListener()
est que addListener()
renvoie une référence à EventTarget
.
nodeEventTarget.emit(type, arg)
Ajouté dans : v15.2.0
type
<string>arg
<any>- Retourne : <boolean>
true
si des auditeurs d’événements enregistrés pour letype
existent, sinonfalse
.
Extension spécifique à Node.js de la classe EventTarget
qui distribue l’arg
à la liste des gestionnaires pour type
.
nodeEventTarget.eventNames()
Ajouté dans : v14.5.0
- Retourne : <string[]>
Extension spécifique à Node.js de la classe EventTarget
qui renvoie un tableau de noms de type
d’événement pour lesquels des auditeurs d’événements sont enregistrés.
nodeEventTarget.listenerCount(type)
Ajouté dans : v14.5.0
Extension spécifique à Node.js de la classe EventTarget
qui renvoie le nombre d’auditeurs d’événements enregistrés pour le type
.
nodeEventTarget.setMaxListeners(n)
Ajouté dans : v14.5.0
n
<number>
Extension spécifique à Node.js de la classe EventTarget
qui définit le nombre maximal d'écouteurs d'événements à n
.
nodeEventTarget.getMaxListeners()
Ajouté dans : v14.5.0
- Returns : <number>
Extension spécifique à Node.js de la classe EventTarget
qui renvoie le nombre maximal d'écouteurs d'événements.
nodeEventTarget.off(type, listener[, options])
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>options
<Object>capture
<boolean>
Returns : <EventTarget> this
Alias spécifique à Node.js pour eventTarget.removeEventListener()
.
nodeEventTarget.on(type, listener)
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>- Returns : <EventTarget> this
Alias spécifique à Node.js pour eventTarget.addEventListener()
.
nodeEventTarget.once(type, listener)
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>- Returns : <EventTarget> this
Extension spécifique à Node.js de la classe EventTarget
qui ajoute un écouteur once
pour le type
d'événement donné. Ceci est équivalent à appeler on
avec l'option once
définie sur true
.
nodeEventTarget.removeAllListeners([type])
Ajouté dans: v14.5.0
type
<string>- Renvoie: <EventTarget> this
Extension spécifique à Node.js de la classe EventTarget
. Si type
est spécifié, supprime tous les auditeurs enregistrés pour type
, sinon supprime tous les auditeurs enregistrés.
nodeEventTarget.removeListener(type, listener[, options])
Ajouté dans: v14.5.0
type
<string>listener
<Function> | <EventListener>options
<Object>capture
<boolean>
Renvoie: <EventTarget> this
Extension spécifique à Node.js de la classe EventTarget
qui supprime le listener
pour le type
donné. La seule différence entre removeListener()
et removeEventListener()
est que removeListener()
renverra une référence à EventTarget
.