Événements
[Stable : 2 - Stable]
Stable : 2 Stabilité : 2 - Stable
Code source : lib/events.js
Une grande partie de l’API principale de Node.js est construite autour d’une architecture événementielle asynchrone 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 à des événements nommés émis par l’objet. En général, les noms d’événements sont des chaînes de caractères en camel case, 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 de manière synchrone. Les valeurs renvoyées par les écouteurs appelés sont ignorées et rejetées.
L’exemple suivant montre une instance EventEmitter
simple 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('un événement s’est produit !')
})
myEmitter.emit('event')
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
console.log('un événement s’est produit !')
})
myEmitter.emit('event')
Passage d’arguments et de this
aux écouteurs
La méthode eventEmitter.emit()
permet de passer un ensemble arbitraire d’arguments aux fonctions écouteurs. Gardez à l’esprit que lorsqu’une fonction écouteur 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)
// Affiche :
// 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)
// Affiche :
// 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, ce faisant, 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)
// Affiche : 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)
// Affiche : a b {}
})
myEmitter.emit('event', 'a', 'b')
Asynchrone vs. synchrone
EventEmitter
appelle tous les écouteurs de manière synchrone dans l'ordre où ils ont été enregistrés. Cela garantit une séquence correcte 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é, puis 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 au sein d'une instance EventEmitter
, l'action typique consiste à émettre un événement 'error'
. Ceux-ci sont traités comme des cas spéciaux 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!'))
// Lève une exception et plante Node.js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('whoops!'))
// Lève une exception et plante Node.js
Pour éviter de planter le processus Node.js, le module domain
peut être utilisé. (Notez cependant que le module node:domain
est déprécié.)
Il est recommandé d'ajouter toujours des écouteurs 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 utilisant le 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!'))
// Lève toujours une exception et plante 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!'))
// Lève toujours une exception et plante Node.js
Capture des rejets de promises
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 en existe une, ou vers le gestionnaire d'événements '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'
générés par le comportement captureRejections
n'ont pas de gestionnaire catch pour éviter les boucles d'erreur infinies : il est recommandé de ne pas utiliser de fonctions async
comme gestionnaires d'événements 'error'
.
Classe : EventEmitter
[Historique]
Version | Modifications |
---|---|
v13.4.0, v12.16.0 | Option captureRejections ajoutée. |
v0.1.26 | Ajoutée 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 écouteurs sont ajoutés et 'removeListener'
lorsque des écouteurs existants sont supprimés.
Il prend en charge l'option suivante :
captureRejections
<booléen> Il active la capture automatique du rejet de promesse. Par défaut :false
.
Événement : 'newListener'
Ajouté dans : v0.1.26
eventName
<chaîne de caractères> | <symbole> Le nom de l'événement écoutélistener
<Fonction> La fonction de gestionnaire d'événements
L'instance EventEmitter
émettra son propre événement 'newListener'
avant qu'un écouteur ne soit ajouté à son tableau interne d'écouteurs.
Les écouteurs enregistrés pour l'événement 'newListener'
reçoivent le nom de l'événement et une référence à l'écouteur en cours d'ajout.
Le fait que l'événement soit déclenché avant l'ajout de l'écouteur a un effet secondaire subtil mais important : tous les écouteurs supplémentaires enregistrés pour le même name
à l'intérieur du rappel 'newListener'
sont insérés avant l'écouteur en cours d'ajout.
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
// Ne faites cela qu'une seule fois pour éviter une boucle infinie
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insérer un nouvel écouteur en tête
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()
// Ne faites cela qu'une seule fois pour éviter une boucle infinie
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insérer un nouvel écouteur en tête
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 à l'aide de .once() , l'argument listener fournit désormais la fonction d'écouteur originale. |
v0.9.3 | Ajouté dans : v0.9.3 |
eventName
<string> | <symbol> Le nom de l'événementlistener
<Function> La fonction de gestionnaire d'événements
L'événement 'removeListener'
est émis après la suppression de l'écouteur listener
.
emitter.addListener(eventName, listener)
Ajouté dans : v0.1.26
eventName
<string> | <symbol>listener
<Function>
Alias de 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 où ils ont été enregistrés, en passant 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 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 paramètres ${parameters} dans le troisième écouteur`)
})
console.log(myEmitter.listeners('event'))
myEmitter.emit('event', 1, 2, 3, 4, 5)
// Affiche :
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Helloooo! premier écouteur
// événement avec paramètres 1, 2 dans le deuxième écouteur
// événement avec 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 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 paramètres ${parameters} dans le troisième écouteur`)
})
console.log(myEmitter.listeners('event'))
myEmitter.emit('event', 1, 2, 3, 4, 5)
// Affiche :
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Helloooo! premier écouteur
// événement avec paramètres 1, 2 dans le deuxième écouteur
// événement avec paramètres 1, 2, 3, 4, 5 dans le troisième écouteur
emitter.eventNames()
Ajouté dans : v6.0.0
- Retourne : <Tableau>
Retourne un tableau listant les événements pour lesquels l'émetteur a enregistré des écouteurs. Les valeurs du tableau sont des chaînes de caractères ou des Symbol
.
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é dans : v1.0.0
- Retourne : <entier>
Retourne la valeur maximale actuelle de l'écouteur pour l' EventEmitter
, qui est soit définie par emitter.setMaxListeners(n)
, soit définie par défaut sur events.defaultMaxListeners
.
emitter.listenerCount(eventName[, listener])
[Historique]
Version | Modifications |
---|---|
v19.8.0, v18.16.0 | Ajout de l'argument listener . |
v3.2.0 | Ajouté dans : v3.2.0 |
eventName
<chaîne de caractères> | <symbole> Le nom de l'événement écoutélistener
<Fonction> La fonction de gestionnaire d'événements- Retourne : <entier>
Retourne le nombre d'écouteurs qui écoutent l'événement nommé eventName
. Si listener
est fourni, il retournera le nombre de fois où l'écouteur est trouvé dans la liste des écouteurs de l'événement.
emitter.listeners(eventName)
[Historique]
Version | Modifications |
---|---|
v7.0.0 | Pour les écouteurs attachés en utilisant .once() , cela renvoie maintenant les écouteurs 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 écouteurs pour l’événement nommé eventName
.
server.on('connection', stream => {
console.log('quelqu’un s’est connecté !')
})
console.log(util.inspect(server.listeners('connection')))
// Affiche : [ [Function] ]
emitter.off(eventName, listener)
Ajouté dans : v10.0.0
eventName
<string> | <symbol>listener
<Function>- Retourne : <EventEmitter>
Alias pour 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 rappel- Retourne : <EventEmitter>
Ajoute la fonction listener
à la fin du tableau des écouteurs pour l’événement nommé eventName
. Aucune vérification n’est effectuée pour voir si l’listener
a déjà été ajouté. Plusieurs appels passant la même combinaison de eventName
et listener
auront pour résultat que listener
sera ajouté et appelé plusieurs fois.
server.on('connection', stream => {
console.log('quelqu’un s’est connecté !')
})
Retourne une référence à l’EventEmitter
, afin que les appels puissent être enchaînés.
Par défaut, les écouteurs d’événements sont appelés dans l’ordre où ils sont ajoutés. La méthode emitter.prependListener()
peut être utilisée comme alternative pour ajouter l’écouteur d’événements au début du tableau des écouteurs.
import { EventEmitter } from 'node:events'
const myEE = new EventEmitter()
myEE.on('foo', () => console.log('a'))
myEE.prependListener('foo', () => console.log('b'))
myEE.emit('foo')
// Affiche :
// 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')
// Affiche :
// 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
unique pour l'événement nommé eventName
. La prochaine fois que eventName
est déclenché, cet écouteur 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 enchaînés.
Par défaut, les écouteurs d'événements sont invoqués dans l'ordre où ils sont ajoutés. La méthode emitter.prependOnceListener()
peut être utilisée comme alternative pour ajouter l'écouteur d'événements au début du tableau des écouteurs.
import { EventEmitter } from 'node:events'
const myEE = new EventEmitter()
myEE.once('foo', () => console.log('a'))
myEE.prependOnceListener('foo', () => console.log('b'))
myEE.emit('foo')
// Affiche :
// 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')
// Affiche :
// 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 écouteurs pour l'événement nommé eventName
. Aucune vérification n'est effectuée pour voir si l'listener
a déjà été ajouté. Plusieurs appels passant la même combinaison de eventName
et listener
entraîneront l'ajout et l'appel de l'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 enchaî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
unique pour l'événement nommé eventName
au début du tableau des écouteurs. La prochaine fois que eventName
sera déclenché, cet écouteur sera supprimé, puis invoqué.
server.prependOnceListener('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.
emitter.removeAllListeners([eventName])
Ajouté dans : v0.1.26
eventName
<string> | <symbol>- Retourne : <EventEmitter>
Supprime tous les écouteurs, ou ceux de l'eventName
spécifié.
Il est déconseillé de supprimer les écouteurs 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 l'listener
spécifié du tableau des écouteurs pour l'événement nommé eventName
.
const callback = stream => {
console.log("quelqu'un s'est connecté !")
}
server.on('connection', callback)
// ...
server.removeListener('connection', callback)
removeListener()
supprimera, au maximum, une instance d'un écouteur du tableau des écouteurs. Si un seul écouteur a été ajouté plusieurs fois au tableau des écouteurs 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 écouteurs qui y sont attachés au moment de l'émission sont appelés dans l'ordre. Cela implique que tous les appels removeListener()
ou removeAllListeners()
après l'émission et avant la fin de l'exécution du dernier écouteur ne les supprimeront pas de l'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'écouteur callbackB mais il sera quand même appelé.
// Tableau d'écouteurs interne au moment de l'émission [callbackA, callbackB]
myEmitter.emit('event')
// Affiche :
// A
// B
// callbackB est maintenant supprimé.
// Tableau d'écouteurs interne [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'écouteur callbackB mais il sera quand même appelé.
// Tableau d'écouteurs interne au moment de l'émission [callbackA, callbackB]
myEmitter.emit('event')
// Affiche :
// A
// B
// callbackB est maintenant supprimé.
// Tableau d'écouteurs interne [callbackA]
myEmitter.emit('event')
// Affiche :
// A
Parce que les écouteurs sont gérés à l'aide d'un tableau interne, l'appel de cette fonction modifiera les index de position de tout écouteur enregistré après l'écouteur en cours de suppression. Cela n'aura pas d'impact sur l'ordre dans lequel les écouteurs sont appelés, mais cela signifie que toutes les copies du tableau des écouteurs telles que retournées par la méthode emitter.listeners()
devront être recréées.
Lorsqu'une seule fonction a été ajoutée plusieurs fois comme gestionnaire pour un seul événement (comme dans l'exemple ci-dessous), removeListener()
supprimera l'instance la plus récemment ajoutée. Dans l'exemple, l'écouteur 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
<entier>- Retourne : <EventEmitter>
Par défaut, les EventEmitter
afficheront un avertissement si plus de 10 écouteurs sont ajoutés pour un événement particulier. Il s'agit d'une valeur par défaut utile qui permet de détecter les fuites de mémoire. La méthode emitter.setMaxListeners()
permet de modifier la limite pour cette instance EventEmitter
spécifique. La valeur peut être définie sur Infinity
(ou 0
) pour indiquer un nombre illimité d'écouteurs.
Retourne une référence à l'objet EventEmitter
, afin que les appels puissent être chaînés.
emitter.rawListeners(eventName)
Ajouté dans : v9.4.0
eventName
<chaîne de caractères> | <symbole>- Retourne : <Function[]>
Retourne une copie du tableau des écouteurs pour l'événement nommé eventName
, y compris 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'))
// Retourne un nouveau tableau avec une fonction `onceWrapper` qui possède une propriété
// `listener` contenant l'écouteur original lié ci-dessus
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]
// Affiche "log once" dans la console et ne supprime pas l'événement `once`
logFnWrapper.listener()
// Affiche "log once" dans la console et supprime l'écouteur
logFnWrapper()
emitter.on('log', () => console.log('log persistently'))
// Retournera un nouveau tableau avec une seule fonction liée par `.on()` ci-dessus
const newListeners = emitter.rawListeners('log')
// Affiche "log persistently" deux fois
newListeners[0]()
emitter.emit('log')
const EventEmitter = require('node:events')
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))
// Retourne un nouveau tableau avec une fonction `onceWrapper` qui possède une propriété
// `listener` contenant l'écouteur original lié ci-dessus
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]
// Affiche "log once" dans la console et ne supprime pas l'événement `once`
logFnWrapper.listener()
// Affiche "log once" dans la console et supprime l'écouteur
logFnWrapper()
emitter.on('log', () => console.log('log persistently'))
// Retournera un nouveau tableau avec une seule fonction liée par `.on()` ci-dessus
const newListeners = emitter.rawListeners('log')
// Affiche "log persistently" deux fois
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é 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('rejet survenu pour', event, 'avec', err, ...args)
this.destroy(err)
}
destroy(err) {
// Détruire la ressource ici.
}
}
const { EventEmitter, captureRejectionSymbol } = require('node:events')
class MyClass extends EventEmitter {
constructor() {
super({ captureRejections: true })
}
[captureRejectionSymbol](err, event, ...args) {
console.log('rejet survenu pour', event, 'avec', err, ...args)
this.destroy(err)
}
destroy(err) {
// Détruire la ressource ici.
}
}
events.defaultMaxListeners
Ajouté dans : v0.11.2
Par défaut, un maximum de 10 écouteurs peuvent être enregistrés pour chaque événement. Cette limite peut être modifiée pour des instances EventEmitter
individuelles à l'aide de 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 erreur 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
permettra l'ajout d'un plus grand nombre d'écouteurs, mais affichera un avertissement de trace sur stderr indiquant qu'une « fuite de mémoire EventEmitter possible » a été détectée. Pour toute instance 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
. S'il est 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'émettront pas d'avertissement.
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.setMaxListeners(emitter.getMaxListeners() + 1)
emitter.once('event', () => {
// faire quelque chose
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', () => {
// faire quelque chose
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0))
})
L'indicateur de ligne de commande --trace-warnings
peut être utilisé pour afficher la trace de la pile pour ces 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 respectivement à l'instance de l'émetteur d'événements, au nom de l'événement et au nombre d'écouteurs attachés. 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 qui ne surveille que les événements 'error'
. Les écouteurs installés à l’aide de ce symbole sont appelés avant les écouteurs 'error'
réguliers.
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 se bloquera 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
, cela se comporte exactement de la même manière que l’appel de .listeners
sur l’émetteur.
Pour les EventTarget
, c’est le seul moyen d’obtenir les écouteurs d’événements pour la cible d’événements. 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 maximal actuel d'écouteurs.
Pour les EventEmitter
, cela se comporte exactement de la même manière que d'appeler .getMaxListeners
sur l'émetteur.
Pour les EventTarget
, c'est le seul moyen d'obtenir le nombre maximal d'écouteurs d'événements pour la cible d'événements. Si le nombre de gestionnaires d'événements sur un seul EventTarget dépasse le maximum défini, l'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()
Le traitement spécial de l'événement 'error'
n'est utilisé 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 traitement spécial :
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'))
// Affiche : 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'))
// Affiche : 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() // Affiche : 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() // Affiche : Waiting for the event was canceled!
Attente de plusieurs événements émis sur process.nextTick()
Il existe un cas particulier à 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, comme la file d'attente process.nextTick()
est vidée avant la file d'attente des microtâches Promise
, et comme 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 intercepter 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 : <booléen>
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
Déprécié depuis : v3.2.0
[Stable : 0 - Déprécié]
Stable : 0 Stabilité : 0 - Déprécié : utiliser emitter.listenerCount()
à la place.
emitter
<EventEmitter> L'émetteur à interrogereventName
<chaîne de caractères> | <symbole> Le nom de l'événement
Une méthode de classe qui renvoie le nombre d'écouteurs pour le eventName
donné enregistré sur l'émetteur donné.
import { EventEmitter, listenerCount } from 'node:events'
const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Affiche : 2
const { EventEmitter, listenerCount } = require('node:events')
const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Affiche : 2
events.on(emitter, eventName[, options])
[Historique]
Version | Modifications |
---|---|
v22.0.0, v20.13.0 | Prise en charge des options highWaterMark et lowWaterMark , pour des raisons 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é dans : v13.6.0, v12.16.0 |
emitter
<EventEmitter>options
<Object>signal
<AbortSignal> Peut être utilisé pour annuler l'attente des événements.close
- <string[]> Noms des événements qui mettront fin à l'itération.highWaterMark
- <integer> Défaut :Number.MAX_SAFE_INTEGER
La limite haute. 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> Défaut :1
La limite basse. L'émetteur est repris 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()
// Emission ultérieure
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 traite
// un événement à la fois (même avec await). Ne pas utiliser
// si une exécution concurrente est requise.
console.log(event) // affiche ['bar'] [42]
}
// Inatteignable ici
const { on, EventEmitter } = require('node:events')
;(async () => {
const ee = new EventEmitter()
// Emission ultérieure
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 traite
// un événement à la fois (même avec await). Ne pas utiliser
// si une exécution concurrente 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 écouteurs lors de la sortie de la boucle. La value
retournée par chaque itération est un tableau composé des arguments de l'événement émis.
Un <AbortSignal> peut être utilisé pour annuler l'attente des événements :
import { on, EventEmitter } from 'node:events'
import process from 'node:process'
const ac = new AbortController()
;(async () => {
const ee = new EventEmitter()
// Emission ultérieure
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 traite
// un événement à la fois (même avec await). Ne pas utiliser
// si une exécution concurrente 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()
// Emission ultérieure
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 traite
// un événement à la fois (même avec await). Ne pas utiliser
// si une exécution concurrente 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 ou plusieurs instances <EventTarget> ou <EventEmitter>. Si aucune n'est spécifiée,n
est défini comme maximum par défaut pour tous les nouveaux objets <EventTarget> et <EventEmitter> 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 - Expérimental]
Stable : 1 Stabilité : 1 - Expérimental
signal
<AbortSignal>listener
<Function> | <EventListener>- Retourne : <Disposable> Un objet Disposable qui supprime l'auditeur
abort
.
Écoute une seule fois l'événement abort
sur le signal
fourni.
Écouter l'événement abort
sur les signaux d'annulation n'est pas sûr et peut entraîner des fuites de ressources car un tiers disposant du 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 facilite l'oubli de la suppression des auditeurs.
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'exécution de l'auditeur.
Retourne un objet 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é 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 leur contexte asynchrone.
import { EventEmitterAsyncResource, EventEmitter } from 'node:events'
import { notStrictEqual, strictEqual } from 'node:assert'
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks'
// Les outils de suivi asynchrone identifieront 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, cependant, s'exécutent dans le même contexte asynchrone que le 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')
// Les outils de suivi asynchrone identifieront 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, cependant, s'exécutent dans le même contexte asynchrone que le emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId)
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId)
})
Promise.resolve().then(() => {
ee1.emit('foo')
ee2.emit('foo')
})
La classe EventEmitterAsyncResource
possède les mêmes méthodes et prend les mêmes options que EventEmitter
et AsyncResource
eux-mêmes.
new events.EventEmitterAsyncResource([options])
options
<Objet>captureRejections
<booléen> Active la capture automatique du rejet de promesse. Par défaut :false
.name
<chaîne de caractères> Le type d'événement asynchrone. Par défaut :new.target.name
.triggerAsyncId
<nombre> L'ID du contexte d'exécution qui a créé cet événement asynchrone. Par défaut :executionAsyncId()
.requireManualDestroy
<booléen> Si défini surtrue
, désactiveemitDestroy
lorsque l'objet est collecté par le garbage collector. Ceci n'a généralement pas besoin d'être défini (même siemitDestroy
est appelé manuellement), sauf si l'asyncId
de la ressource est récupéré et queemitDestroy
de l'API sensible est appelé avec. Lorsqu'il est défini surfalse
, l'appelemitDestroy
lors de la collecte des ordures n'aura lieu que s'il existe au moins un hookdestroy
actif. Par défaut :false
.
eventemitterasyncresource.asyncId
- Type : <nombre> L'
asyncId
unique attribué à la ressource.
eventemitterasyncresource.asyncResource
- Type : La <AsyncResource> sous-jacente.
L'objet AsyncResource
renvoyé possède une propriété eventEmitter
supplémentaire qui fournit une référence à ce EventEmitterAsyncResource
.
eventemitterasyncresource.emitDestroy()
Appelle tous les hooks destroy
. Ceci ne devrait être appelé qu'une seule fois. Une erreur sera levée si elle est appelée plus d'une fois. Ceci 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 passé au constructeurAsyncResource
.
API EventTarget
et Event
[Historique]
Version | Modifications |
---|---|
v16.0.0 | Gestion des erreurs EventTarget modifiée. |
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 principales 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 clés entre 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 type
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 de gestionnaire est appelée avec l'argument event
passé à la fonction eventTarget.dispatchEvent()
.
Des fonctions asynchrones peuvent être utilisées comme écouteurs d'événements. Si une fonction de gestionnaire asynchrone est rejetée, le rejet est capturé et géré comme décrit dans la section Gestion des erreurs EventTarget
.
Une erreur levée par une fonction de gestionnaire n'empêche pas les autres gestionnaires d'être appelés.
La valeur de retour d'une fonction de gestionnaire est ignorée.
Les gestionnaires sont toujours appelés dans l'ordre où ils ont été ajoutés.
Les fonctions de gestionnaire 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 promesse 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.
Le fait de lever une exception dans un écouteur d'événements n'empêchera pas l'invocation des autres gestionnaires enregistrés.
EventTarget
n'implémente aucun traitement par défaut spécial 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 déprécié et changera dans une future version pour aligner EventTarget
avec les autres API Node.js. Tout code reposant sur l'événement process.on('error')
doit être aligné avec le nouveau comportement.
Classe : Event
[Historique]
Version | Modifications |
---|---|
v15.0.0 | La classe Event est désormais disponible via l'objet global. |
v14.5.0 | Ajouté 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é dans : v14.5.0
- Type : <booléen> Retourne toujours
false
.
Ceci n'est pas utilisé dans Node.js et est fourni uniquement pour des raisons de complétude.
event.cancelBubble
Ajouté dans : v14.5.0
[Stable : 3 - Hérité]
Stable : 3 Stabilité : 3 - Hérité : Utilisez event.stopPropagation()
à la place.
- Type : <booléen>
Alias de event.stopPropagation()
s'il est défini sur true
. Ceci n'est pas utilisé dans Node.js et est fourni uniquement pour des raisons de complétude.
event.cancelable
Ajouté dans : v14.5.0
- Type : <booléen> Vrai si l'événement a été créé avec l'option
cancelable
.
event.composed
Ajouté dans : v14.5.0
- Type : <booléen> Retourne toujours
false
.
Ceci n'est pas utilisé dans Node.js et est fourni uniquement pour des raisons de complétude.
event.composedPath()
Ajouté dans : v14.5.0
Retourne un tableau contenant le EventTarget
actuel comme seule entrée ou vide si l'événement n'est pas en cours d'envoi. Ceci n'est pas utilisé dans Node.js et est fourni uniquement pour des raisons de complétude.
event.currentTarget
Ajouté dans : v14.5.0
- Type : <EventTarget> Le
EventTarget
qui envoie l'événement.
Alias de event.target
.
event.defaultPrevented
Ajouté dans : v14.5.0
- Type : <booléen>
Est true
si cancelable
est true
et que event.preventDefault()
a été appelé.
event.eventPhase
Ajouté dans : v14.5.0
- Type : <nombre> Retourne
0
lorsqu'un événement n'est pas en cours d'envoi,2
lorsqu'il est en cours d'envoi.
Ceci n'est pas utilisé dans Node.js et est fourni uniquement pour des raisons de complétude.
event.initEvent(type[, bubbles[, cancelable]])
Ajouté dans : v19.5.0
[Stable : 3 - Hérité]
Stable : 3 Stabilité : 3 - Hérité : La spécification WHATWG la considère comme obsolète et les utilisateurs ne devraient pas du tout l'utiliser.
type
<chaîne de caractères>bubbles
<booléen>cancelable
<booléen>
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 pour des raisons de complétude.
event.isTrusted
Ajouté dans : v14.5.0
- Type : <booléen>
L'événement <AbortSignal> "abort"
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 - Hérité]
Stable : 3 Stabilité : 3 - Hérité : 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 pour des raisons de complétude.
event.srcElement
Ajouté dans : v14.5.0
[Stable : 3 - Hérité]
Stable : 3 Stabilité : 3 - Hérité : 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 que l’écouteur courant soit terminé.
event.stopPropagation()
Ajouté dans : v14.5.0
Ceci n’est pas utilisé dans Node.js et est fourni uniquement pour des raisons de complétude.
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 lorsque l’objet Event
a été créé.
event.type
Ajouté dans : v14.5.0
- Type : <string>
L’identifiant du type d’événement.
Classe : EventTarget
[Historique]
Version | Modifications |
---|---|
v15.0.0 | La classe EventTarget est maintenant 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> Lorsquetrue
, le gestionnaire est automatiquement supprimé lorsqu'il est invoqué pour la première fois. Valeur par défaut :false
.passive
<boolean> Lorsquetrue
, sert d'indication que le gestionnaire n'appellera pas la méthodepreventDefault()
de l'objetEvent
. Valeur par défaut :false
.capture
<boolean> Non utilisé directement par Node.js. Ajouté pour l'exhaustivité de l'API. Valeur par défaut :false
.signal
<AbortSignal> Le gestionnaire sera supprimé lorsque la méthodeabort()
de l'objetAbortSignal
donné est appelée.
Ajoute un nouveau gestionnaire pour l'événement type
. Un listener
donné est ajouté 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 de type 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 gestionnaires d'événements enregistrés selon les spécifications EventTarget
. Plus précisément, l'option capture
est utilisée comme partie 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 seconde 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>- Retourne : <boolean>
true
si la valeur de l'attributcancelable
de l'événement est false ou si sa méthodepreventDefault()
n'a pas été invoquée,false
sinon.
Déclenche l'événement event
sur la liste des gestionnaires pour event.type
.
Les écouteurs d'événements enregistrés sont invoqués de manière synchrone dans l'ordre de leur enregistrement.
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'événement type
.
Classe : CustomEvent
[Historique]
Version | Modifications |
---|---|
v23.0.0 | N'est plus expérimental. |
v22.1.0, v20.13.0 | CustomEvent est maintenant stable. |
v19.0.0 | N'est plus derrière le drapeau 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
- Étend : <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 maintenant 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> Retourne les données personnalisées passées lors de l'initialisation.
Lecture seule.
Classe : NodeEventTarget
Ajouté dans : v14.5.0
- Étend : <EventTarget>
NodeEventTarget
est une extension Node.js spécifique à 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 Node.js spécifique à la classe EventTarget
qui émule l'API EventEmitter
équivalente. La seule différence entre addListener()
et addEventListener()
est que addListener()
retournera une référence à EventTarget
.
nodeEventTarget.emit(type, arg)
Ajouté dans : v15.2.0
type
<string>arg
<any>- Retourne : <boolean>
true
si des écouteurs d'événements enregistrés pour letype
existent, sinonfalse
.
Extension Node.js spécifique à la classe EventTarget
qui envoie l'argument arg
à la liste des gestionnaires pour type
.
nodeEventTarget.eventNames()
Ajouté dans : v14.5.0
- Retourne : <string[]>
Extension Node.js spécifique à la classe EventTarget
qui retourne un tableau de noms de type
d'événements pour lesquels des écouteurs d'événements sont enregistrés.
nodeEventTarget.listenerCount(type)
Ajouté dans : v14.5.0
Extension Node.js spécifique à la classe EventTarget
qui retourne le nombre d'écouteurs d'événements enregistrés pour le type
.
nodeEventTarget.setMaxListeners(n)
Ajouté dans : v14.5.0
n
<number>
Extension Node.js spécifique à la classe EventTarget
qui définit le nombre maximal d'écouteurs d'événements à n
.
nodeEventTarget.getMaxListeners()
Ajouté dans : v14.5.0
- Retourne : <number>
Extension Node.js spécifique à la classe EventTarget
qui retourne 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>
Retourne : <EventTarget> this
Alias Node.js spécifique pour eventTarget.removeEventListener()
.
nodeEventTarget.on(type, listener)
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>- Retourne : <EventTarget> this
Alias Node.js spécifique pour eventTarget.addEventListener()
.
nodeEventTarget.once(type, listener)
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>- Retourne : <EventTarget> this
Extension Node.js spécifique à la classe EventTarget
qui ajoute un écouteur once
pour l'événement type
donné. Ceci équivaut à appeler on
avec l'option once
définie à true
.
nodeEventTarget.removeAllListeners([type])
Ajouté dans : v14.5.0
type
<string>- Retourne : <EventTarget> this
Extension Node.js spécifique à la classe EventTarget
. Si type
est spécifié, supprime tous les écouteurs enregistrés pour type
, sinon supprime tous les écouteurs enregistrés.
nodeEventTarget.removeListener(type, listener[, options])
Ajouté dans : v14.5.0
type
<string>listener
<Function> | <EventListener>options
<Object>capture
<boolean>
Retourne : <EventTarget> this
Extension Node.js spécifique à la classe EventTarget
qui supprime l’écouteur
pour le type
donné. La seule différence entre removeListener()
et removeEventListener()
est que removeListener()
retournera une référence à EventTarget
.