Skip to content

É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.

js
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')
js
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é.

js
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')
js
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 :

js
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')
js
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() :

js
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')
js
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.

js
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
js
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é.

js
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
js
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.

js
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
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'.

js
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
js
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.

js
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
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 :

js
import { EventEmitter } from 'node:events'
const ee = new EventEmitter()
ee.on('something', async value => {
  throw new Error('kaboom')
})
js
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.

js
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
js
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.

js
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)
js
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]

VersionModifications
v13.4.0, v12.16.0Option captureRejections ajoutée.
v0.1.26Ajoutée dans : v0.1.26

La classe EventEmitter est définie et exposée par le module node:events :

js
import { EventEmitter } from 'node:events'
js
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 :

Événement : 'newListener'

Ajouté dans : v0.1.26

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.

js
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
js
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]

VersionModifications
v6.1.0, v4.7.0Pour les écouteurs attachés à l'aide de .once(), l'argument listener fournit désormais la fonction d'écouteur originale.
v0.9.3Ajouté dans : v0.9.3

L'événement 'removeListener' est émis après la suppression de l'écouteur listener.

emitter.addListener(eventName, listener)

Ajouté dans : v0.1.26

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.

js
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
js
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 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.

js
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) ]
js
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 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]

VersionModifications
v19.8.0, v18.16.0Ajout de l'argument listener.
v3.2.0Ajouté dans : v3.2.0

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]

VersionModifications
v7.0.0Pour les écouteurs attachés en utilisant .once(), cela renvoie maintenant les écouteurs originaux au lieu des fonctions wrapper.
v0.1.26Ajouté dans : v0.1.26

Retourne une copie du tableau des écouteurs pour l’événement nommé eventName.

js
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

Alias pour emitter.removeListener().

emitter.on(eventName, listener)

Ajouté dans : v0.1.101

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.

js
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.

js
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
js
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

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é.

js
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.

js
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
js
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

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.

js
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

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é.

js
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

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

Supprime l'listener spécifié du tableau des écouteurs pour l'événement nommé eventName.

js
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.

js
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
js
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é :

js
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')
js
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

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

Retourne une copie du tableau des écouteurs pour l'événement nommé eventName, y compris les wrappers (tels que ceux créés par .once()).

js
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')
js
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]

VersionModifications
v17.4.0, v16.14.0N'est plus expérimental.
v13.4.0, v12.16.0Ajouté 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').

js
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.
  }
}
js
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.

js
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))
})
js
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

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.

js
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] ]
}
js
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

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.

js
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
}
js
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]

VersionModifications
v15.0.0L'option signal est désormais prise en charge.
v11.13.0, v10.16.0Ajouté dans : v11.13.0, v10.16.0

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'.

js
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)
}
js
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 :

js
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
js
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 :

js
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!
js
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.

js
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'))
js
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():

js
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'))
js
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]

VersionModifications
v17.4.0, v16.14.0N'est plus expérimental.
v13.4.0, v12.16.0Ajouté 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]

VersionModifications
v17.4.0, v16.14.0N'est plus expérimental.
v13.4.0, v12.16.0Ajouté 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.

Une méthode de classe qui renvoie le nombre d'écouteurs pour le eventName donné enregistré sur l'émetteur donné.

js
import { EventEmitter, listenerCount } from 'node:events'

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Affiche : 2
js
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]

VersionModifications
v22.0.0, v20.13.0Prise en charge des options highWaterMark et lowWaterMark, pour des raisons de cohérence. Les anciennes options sont toujours prises en charge.
v20.0.0Les options close, highWatermark et lowWatermark sont désormais prises en charge.
v13.6.0, v12.16.0Ajouté dans : v13.6.0, v12.16.0
  • emitter <EventEmitter>

  • eventName <string> | <symbol> Le nom de l'événement écouté

  • 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éthodes pause() et resume().
    • 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éthodes pause() et resume().
  • Retourne : <AsyncIterator> qui itère sur les événements eventName émis par l'emitter

js
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
js
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 :

js
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())
js
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

js
import { setMaxListeners, EventEmitter } from 'node:events'

const target = new EventTarget()
const emitter = new EventEmitter()

setMaxListeners(5, target, emitter)
js
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

É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.

js
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]()
  }
}
js
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.

js
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')
})
js
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 sur true, désactive emitDestroy lorsque l'objet est collecté par le garbage collector. Ceci n'a généralement pas besoin d'être défini (même si emitDestroy est appelé manuellement), sauf si l'asyncId de la ressource est récupéré et que emitDestroy de l'API sensible est appelé avec. Lorsqu'il est défini sur false, l'appel emitDestroy lors de la collecte des ordures n'aura lieu que s'il existe au moins un hook destroy actif. Par défaut : false.

eventemitterasyncresource.asyncId

  • Type : <nombre> L'asyncId unique attribué à la ressource.

eventemitterasyncresource.asyncResource

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 constructeur AsyncResource.

API EventTarget et Event

[Historique]

VersionModifications
v16.0.0Gestion des erreurs EventTarget modifiée.
v15.4.0N'est plus expérimental.
v15.0.0Les classes EventTarget et Event sont maintenant disponibles en tant que globales.
v14.5.0Ajouté 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.

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.

js
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]

VersionModifications
v15.0.0La classe Event est désormais disponible via l'objet global.
v14.5.0Ajouté 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

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.

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

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

Alias de event.target.

event.defaultPrevented

Ajouté dans : v14.5.0

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.

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

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

L’horodatage en millisecondes lorsque l’objet Event a été créé.

event.type

Ajouté dans : v14.5.0

L’identifiant du type d’événement.

Classe : EventTarget

[Historique]

VersionModifications
v15.0.0La classe EventTarget est maintenant disponible via l’objet global.
v14.5.0Ajouté dans : v14.5.0

eventTarget.addEventListener(type, listener[, options])

[Historique]

VersionModifications
v15.4.0Ajout de la prise en charge de l'option signal.
v14.5.0Ajouté dans : v14.5.0
  • type <string>
  • listener <Function> | <EventListener>
  • options <Object>
    • once <boolean> Lorsque true, le gestionnaire est automatiquement supprimé lorsqu'il est invoqué pour la première fois. Valeur par défaut : false.
    • passive <boolean> Lorsque true, sert d'indication que le gestionnaire n'appellera pas la méthode preventDefault() de l'objet Event. 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éthode abort() de l'objet AbortSignal 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.

js
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'attribut cancelable de l'événement est false ou si sa méthode preventDefault() 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

Supprime le listener de la liste des gestionnaires pour l'événement type.

Classe : CustomEvent

[Historique]

VersionModifications
v23.0.0N'est plus expérimental.
v22.1.0, v20.13.0CustomEvent est maintenant stable.
v19.0.0N'est plus derrière le drapeau CLI --experimental-global-customevent.
v18.7.0, v16.17.0Ajouté dans : v18.7.0, v16.17.0

[Stable : 2 - Stable]

Stable : 2 Stabilité : 2 - Stable

L'objet CustomEvent est une adaptation de l'API Web CustomEvent. Les instances sont créées en interne par Node.js.

event.detail

[Historique]

VersionModifications
v22.1.0, v20.13.0CustomEvent est maintenant stable.
v18.7.0, v16.17.0Ajouté 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

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

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 le type existent, sinon false.

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

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

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

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

Alias Node.js spécifique pour eventTarget.removeEventListener().

nodeEventTarget.on(type, listener)

Ajouté dans : v14.5.0

Alias Node.js spécifique pour eventTarget.addEventListener().

nodeEventTarget.once(type, listener)

Ajouté dans : v14.5.0

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

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

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.