Skip to content

Ereignisse

[Stabil: 2 - Stabil]

Stabil: 2 Stabilität: 2 - Stabil

Quellcode: lib/events.js

Ein Großteil der Node.js-Kern-API basiert auf einer idiomatischen asynchronen ereignisgesteuerten Architektur, in der bestimmte Arten von Objekten (als "Emitter" bezeichnet) benannte Ereignisse auslösen, die dazu führen, dass Function-Objekte ("Listener") aufgerufen werden.

Beispielsweise: Ein net.Server-Objekt sendet ein Ereignis jedes Mal, wenn ein Peer eine Verbindung zu ihm herstellt; ein fs.ReadStream sendet ein Ereignis, wenn die Datei geöffnet wird; ein Stream sendet ein Ereignis, wenn Daten zum Lesen verfügbar sind.

Alle Objekte, die Ereignisse auslösen, sind Instanzen der Klasse EventEmitter. Diese Objekte stellen eine Funktion eventEmitter.on() bereit, mit der eine oder mehrere Funktionen an benannte Ereignisse angehängt werden können, die vom Objekt ausgelöst werden. Typischerweise sind Ereignisnamen Camel-Case-Strings, aber jeder gültige JavaScript-Eigenschaftsschlüssel kann verwendet werden.

Wenn das EventEmitter-Objekt ein Ereignis auslöst, werden alle an dieses spezifische Ereignis angehängten Funktionen synchron aufgerufen. Alle von den aufgerufenen Listenern zurückgegebenen Werte werden ignoriert und verworfen.

Das folgende Beispiel zeigt eine einfache EventEmitter-Instanz mit einem einzigen Listener. Die Methode eventEmitter.on() wird verwendet, um Listener zu registrieren, während die Methode eventEmitter.emit() verwendet wird, um das Ereignis auszulösen.

js
import { EventEmitter } from 'node:events'

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
  console.log('ein Ereignis ist aufgetreten!')
})
myEmitter.emit('event')
js
const EventEmitter = require('node:events')

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
  console.log('ein Ereignis ist aufgetreten!')
})
myEmitter.emit('event')

Übergeben von Argumenten und this an Listener

Die Methode eventEmitter.emit() ermöglicht es, eine beliebige Anzahl von Argumenten an die Listener-Funktionen zu übergeben. Beachten Sie, dass bei Aufruf einer gewöhnlichen Listener-Funktion das Standard-this-Schlüsselwort absichtlich so gesetzt ist, dass es auf die EventEmitter-Instanz verweist, an die der Listener angehängt ist.

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)
  // Gibt aus:
  //   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)
  // Gibt aus:
  //   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')

Es ist möglich, ES6-Arrow-Funktionen als Listener zu verwenden. In diesem Fall verweist das this-Schlüsselwort jedoch nicht mehr auf die EventEmitter-Instanz:

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  console.log(a, b, this)
  // Gibt aus: 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)
  // Gibt aus: a b {}
})
myEmitter.emit('event', 'a', 'b')

Asynchron vs. synchron

Die EventEmitter ruft alle Listener synchron in der Reihenfolge auf, in der sie registriert wurden. Dies stellt die richtige Reihenfolge der Ereignisse sicher und hilft, Race Conditions und Logikfehler zu vermeiden. Bei Bedarf können Listener-Funktionen mit den Methoden setImmediate() oder process.nextTick() in einen asynchronen Betriebsmodus wechseln:

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

Ereignisse nur einmal behandeln

Wenn ein Listener mit der Methode eventEmitter.on() registriert wird, wird dieser Listener jedes Mal aufgerufen, wenn das benannte Ereignis emittiert wird.

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

Mit der Methode eventEmitter.once() ist es möglich, einen Listener zu registrieren, der höchstens einmal für ein bestimmtes Ereignis aufgerufen wird. Sobald das Ereignis emittiert wird, wird der Listener entfernt und danach aufgerufen.

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

Fehlerereignisse

Wenn in einer EventEmitter-Instanz ein Fehler auftritt, wird üblicherweise ein 'error'-Ereignis emittiert. Diese werden in Node.js als Sonderfälle behandelt.

Wenn ein EventEmitter nicht mindestens einen registrierten Listener für das 'error'-Ereignis hat und ein 'error'-Ereignis emittiert wird, wird der Fehler ausgelöst, eine Stack-Trace wird ausgegeben und der Node.js-Prozess wird beendet.

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('whoops!'))
// Löst einen Fehler aus und stürzt Node.js ab
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('whoops!'))
// Löst einen Fehler aus und stürzt Node.js ab

Um das Abstürzen des Node.js-Prozesses zu verhindern, kann das Modul domain verwendet werden. (Beachten Sie jedoch, dass das Modul node:domain veraltet ist.)

Als Best Practice sollten immer Listener für die 'error'-Ereignisse hinzugefügt werden.

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!'))
// Gibt aus: 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!'))
// Gibt aus: whoops! there was an error

Es ist möglich, 'error'-Ereignisse zu überwachen, ohne den emittierten Fehler zu verarbeiten, indem ein Listener mit dem Symbol events.errorMonitor installiert wird.

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öst immer noch einen Fehler aus und stürzt Node.js ab
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öst immer noch einen Fehler aus und stürzt Node.js ab

Abfangen von Promise-Ablehnungen

Die Verwendung von async-Funktionen mit Ereignis-Handlern ist problematisch, da dies im Falle einer geworfenen Ausnahme zu einer unbehandelten Ablehnung führen kann:

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

Die Option captureRejections im EventEmitter-Konstruktor oder die globale Einstellung ändern dieses Verhalten, indem ein .then(undefined, handler)-Handler an das Promise angefügt wird. Dieser Handler leitet die Ausnahme asynchron an die Methode Symbol.for('nodejs.rejection') weiter, falls vorhanden, oder an den Ereignis-Handler 'error', falls keiner vorhanden ist.

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

Das Setzen von events.captureRejections = true ändert die Standardeinstellung für alle neuen Instanzen von 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)

Die 'error'-Ereignisse, die durch das captureRejections-Verhalten generiert werden, haben keinen Catch-Handler, um unendliche Fehlerschleifen zu vermeiden: Es wird empfohlen, keine async-Funktionen als 'error'-Ereignis-Handler zu verwenden.

Klasse: EventEmitter

[Historie]

VersionÄnderungen
v13.4.0, v12.16.0Option captureRejections hinzugefügt.
v0.1.26Hinzugefügt in: v0.1.26

Die Klasse EventEmitter wird vom Modul node:events definiert und bereitgestellt:

js
import { EventEmitter } from 'node:events'
js
const EventEmitter = require('node:events')

Alle EventEmitter geben das Ereignis 'newListener' aus, wenn neue Listener hinzugefügt werden, und 'removeListener', wenn vorhandene Listener entfernt werden.

Es unterstützt die folgende Option:

Ereignis: 'newListener'

Hinzugefügt in: v0.1.26

Die EventEmitter-Instanz gibt ihr eigenes 'newListener'-Ereignis aus, bevor ein Listener zu ihrem internen Listener-Array hinzugefügt wird.

Listener, die für das Ereignis 'newListener' registriert sind, erhalten den Ereignisnamen und einen Verweis auf den hinzuzufügenden Listener.

Die Tatsache, dass das Ereignis vor dem Hinzufügen des Listeners ausgelöst wird, hat eine subtile, aber wichtige Nebenwirkung: Alle zusätzlichen Listener, die für denselben name innerhalb des 'newListener'-Callbacks registriert werden, werden vor dem Listener eingefügt, der gerade hinzugefügt wird.

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
// Nur einmal machen, damit wir nicht endlos schleifen
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Neuen Listener vorne einfügen
    myEmitter.on('event', () => {
      console.log('B')
    })
  }
})
myEmitter.on('event', () => {
  console.log('A')
})
myEmitter.emit('event')
// Gibt aus:
//   B
//   A
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
// Nur einmal machen, damit wir nicht endlos schleifen
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Neuen Listener vorne einfügen
    myEmitter.on('event', () => {
      console.log('B')
    })
  }
})
myEmitter.on('event', () => {
  console.log('A')
})
myEmitter.emit('event')
// Gibt aus:
//   B
//   A

Ereignis: 'removeListener'

[Verlauf]

VersionÄnderungen
v6.1.0, v4.7.0Für Listener, die mit .once() hinzugefügt wurden, liefert das Argument listener nun die ursprüngliche Listener-Funktion.
v0.9.3Hinzugefügt in: v0.9.3

Das Ereignis 'removeListener' wird nach dem Entfernen des listener emittiert.

emitter.addListener(eventName, listener)

Hinzugefügt in: v0.1.26

Alias für emitter.on(eventName, listener).

emitter.emit(eventName[, ...args])

Hinzugefügt in: v0.1.26

Ruft synchron jeden der für das Ereignis mit dem Namen eventName registrierten Listener in der Reihenfolge ihrer Registrierung auf und übergibt die angegebenen Argumente an jeden.

Gibt true zurück, wenn das Ereignis Listener hatte, andernfalls false.

js
import { EventEmitter } from 'node:events'
const myEmitter = new EventEmitter()

// Erster Listener
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! erster Listener')
})
// Zweiter Listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`Ereignis mit Parametern ${arg1}, ${arg2} im zweiten Listener`)
})
// Dritter Listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ')
  console.log(`Ereignis mit Parametern ${parameters} im dritten Listener`)
})

console.log(myEmitter.listeners('event'))

myEmitter.emit('event', 1, 2, 3, 4, 5)

// Ausgabe:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// Helloooo! erster Listener
// Ereignis mit Parametern 1, 2 im zweiten Listener
// Ereignis mit Parametern 1, 2, 3, 4, 5 im dritten Listener
js
const EventEmitter = require('node:events')
const myEmitter = new EventEmitter()

// Erster Listener
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! erster Listener')
})
// Zweiter Listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`Ereignis mit Parametern ${arg1}, ${arg2} im zweiten Listener`)
})
// Dritter Listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ')
  console.log(`Ereignis mit Parametern ${parameters} im dritten Listener`)
})

console.log(myEmitter.listeners('event'))

myEmitter.emit('event', 1, 2, 3, 4, 5)

// Ausgabe:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// Helloooo! erster Listener
// Ereignis mit Parametern 1, 2 im zweiten Listener
// Ereignis mit Parametern 1, 2, 3, 4, 5 im dritten Listener

emitter.eventNames()

Hinzugefügt in: v6.0.0

Gibt ein Array zurück, das die Ereignisse auflistet, für die der Emitter Listener registriert hat. Die Werte im Array sind Zeichenketten oder Symbole.

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())
// Gibt aus: [ '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())
// Gibt aus: [ 'foo', 'bar', Symbol(symbol) ]

emitter.getMaxListeners()

Hinzugefügt in: v1.0.0

Gibt den aktuellen Maximalwert für Listener für den EventEmitter zurück, der entweder durch emitter.setMaxListeners(n) gesetzt wird oder standardmäßig events.defaultMaxListeners entspricht.

emitter.listenerCount(eventName[, listener])

[Verlauf]

VersionÄnderungen
v19.8.0, v18.16.0Das Argument listener hinzugefügt.
v3.2.0Hinzugefügt in: v3.2.0

Gibt die Anzahl der Listener zurück, die auf das Ereignis mit dem Namen eventName lauschen. Wenn listener angegeben ist, wird zurückgegeben, wie oft der Listener in der Liste der Listener des Ereignisses gefunden wird.

emitter.listeners(eventName)

[Verlauf]

VersionÄnderungen
v7.0.0Für Listener, die mit .once() hinzugefügt wurden, werden jetzt die ursprünglichen Listener anstelle von Wrapper-Funktionen zurückgegeben.
v0.1.26Hinzugefügt in: v0.1.26

Gibt eine Kopie des Arrays der Listener für das Ereignis mit dem Namen eventName zurück.

js
server.on('connection', stream => {
  console.log('someone connected!')
})
console.log(util.inspect(server.listeners('connection')))
// Gibt aus: [ [Function] ]

emitter.off(eventName, listener)

Hinzugefügt in: v10.0.0

Alias für emitter.removeListener().

emitter.on(eventName, listener)

Hinzugefügt in: v0.1.101

Fügt die listener-Funktion an das Ende des Listener-Arrays für das Ereignis mit dem Namen eventName hinzu. Es werden keine Prüfungen durchgeführt, um zu sehen, ob der listener bereits hinzugefügt wurde. Mehrere Aufrufe mit der gleichen Kombination aus eventName und listener führen dazu, dass der listener mehrfach hinzugefügt und aufgerufen wird.

js
server.on('connection', stream => {
  console.log('someone connected!')
})

Gibt eine Referenz auf den EventEmitter zurück, so dass Aufrufe verkettet werden können.

Standardmäßig werden Ereignislistener in der Reihenfolge ihrer Hinzufügung aufgerufen. Die Methode emitter.prependListener() kann alternativ verwendet werden, um den Ereignislistener an den Anfang des Listener-Arrays hinzuzufügen.

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')
// Gibt aus:
//   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')
// Gibt aus:
//   b
//   a

emitter.once(eventName, listener)

Hinzugefügt in: v0.3.0

Fügt eine einmalige listener-Funktion für das Ereignis mit dem Namen eventName hinzu. Beim nächsten Auslösen von eventName wird dieser Listener entfernt und anschließend aufgerufen.

js
server.once('connection', stream => {
  console.log('Ah, wir haben unseren ersten Benutzer!')
})

Gibt eine Referenz auf den EventEmitter zurück, sodass Aufrufe verkettet werden können.

Standardmäßig werden Ereignislistener in der Reihenfolge ihres Hinzufügens aufgerufen. Die Methode emitter.prependOnceListener() kann alternativ verwendet werden, um den Ereignislistener an den Anfang des Listeners-Arrays hinzuzufügen.

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')
// Ausgabe:
//   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')
// Ausgabe:
//   b
//   a

emitter.prependListener(eventName, listener)

Hinzugefügt in: v6.0.0

Fügt die listener-Funktion an den Anfang des Listeners-Arrays für das Ereignis mit dem Namen eventName hinzu. Es werden keine Prüfungen durchgeführt, ob der listener bereits hinzugefügt wurde. Mehrere Aufrufe mit der gleichen Kombination aus eventName und listener führen dazu, dass der listener mehrmals hinzugefügt und aufgerufen wird.

js
server.prependListener('connection', stream => {
  console.log('jemand verbunden!')
})

Gibt eine Referenz auf den EventEmitter zurück, sodass Aufrufe verkettet werden können.

emitter.prependOnceListener(eventName, listener)

Hinzugefügt in: v6.0.0

Fügt eine einmalige listener-Funktion für das Ereignis mit dem Namen eventName an den Anfang des Listener-Arrays hinzu. Beim nächsten Auslösen von eventName wird dieser Listener entfernt und anschließend aufgerufen.

js
server.prependOnceListener('connection', stream => {
  console.log('Ah, wir haben unseren ersten Benutzer!')
})

Gibt eine Referenz auf den EventEmitter zurück, sodass Aufrufe verkettet werden können.

emitter.removeAllListeners([eventName])

Hinzugefügt in: v0.1.26

Entfernt alle Listener oder diejenigen des angegebenen eventName.

Es ist schlechte Praxis, Listener zu entfernen, die an anderer Stelle im Code hinzugefügt wurden, insbesondere wenn die EventEmitter-Instanz von einer anderen Komponente oder einem anderen Modul erstellt wurde (z. B. Sockets oder Dateistreams).

Gibt eine Referenz auf den EventEmitter zurück, sodass Aufrufe verkettet werden können.

emitter.removeListener(eventName, listener)

Hinzugefügt in: v0.1.26

Entfernt den angegebenen listener aus dem Listener-Array für das Ereignis mit dem Namen eventName.

js
const callback = stream => {
  console.log('jemand verbunden!')
}
server.on('connection', callback)
// ...
server.removeListener('connection', callback)

removeListener() entfernt höchstens eine Instanz eines Listeners aus dem Listener-Array. Wenn ein einzelner Listener mehrmals dem Listener-Array für das angegebene eventName hinzugefügt wurde, muss removeListener() mehrmals aufgerufen werden, um jede Instanz zu entfernen.

Sobald ein Ereignis ausgelöst wird, werden alle zu diesem Zeitpunkt angehängten Listener der Reihe nach aufgerufen. Dies bedeutet, dass alle removeListener()- oder removeAllListeners()-Aufrufe nach dem Auslösen und vor dem Abschluss der Ausführung des letzten Listeners diese nicht aus der laufenden emit()-Ausführung entfernen. Nachfolgende Ereignisse verhalten sich wie erwartet.

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 entfernt Listener callbackB, aber er wird trotzdem aufgerufen.
// Internes Listener-Array zum Zeitpunkt des emit [callbackA, callbackB]
myEmitter.emit('event')
// Ausgabe:
//   A
//   B

// callbackB wurde nun entfernt.
// Internes Listener-Array [callbackA]
myEmitter.emit('event')
// Ausgabe:
//   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 entfernt Listener callbackB, aber er wird trotzdem aufgerufen.
// Internes Listener-Array zum Zeitpunkt des emit [callbackA, callbackB]
myEmitter.emit('event')
// Ausgabe:
//   A
//   B

// callbackB wurde nun entfernt.
// Internes Listener-Array [callbackA]
myEmitter.emit('event')
// Ausgabe:
//   A

Da Listener mit einem internen Array verwaltet werden, ändert dieser Aufruf die Positionsindizes aller Listener, die nach dem zu entfernenden Listener registriert wurden. Dies hat keinen Einfluss auf die Reihenfolge, in der die Listener aufgerufen werden, bedeutet aber, dass alle Kopien des Listener-Arrays, wie sie von der Methode emitter.listeners() zurückgegeben werden, neu erstellt werden müssen.

Wenn eine einzelne Funktion mehrmals als Handler für ein einzelnes Ereignis hinzugefügt wurde (wie im Beispiel unten), entfernt removeListener() die zuletzt hinzugefügte Instanz. Im Beispiel wird der once('ping')-Listener entfernt:

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

Gibt eine Referenz auf den EventEmitter zurück, sodass Aufrufe verkettet werden können.

emitter.setMaxListeners(n)

Hinzugefügt in: v0.3.5

Standardmäßig geben EventEmitter-Objekte eine Warnung aus, wenn mehr als 10 Listener für ein bestimmtes Ereignis hinzugefügt werden. Dies ist eine nützliche Standardeinstellung, die hilft, Speicherlecks zu finden. Die Methode emitter.setMaxListeners() ermöglicht es, diese Grenze für diese spezifische EventEmitter-Instanz zu ändern. Der Wert kann auf Infinity (oder 0) gesetzt werden, um eine unbegrenzte Anzahl von Listenern anzugeben.

Gibt eine Referenz auf den EventEmitter zurück, sodass Aufrufe verkettet werden können.

emitter.rawListeners(eventName)

Hinzugefügt in: v9.4.0

Gibt eine Kopie des Arrays der Listener für das Ereignis mit dem Namen eventName zurück, einschließlich aller Wrapper (wie z. B. die von .once() erstellten).

js
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))

// Gibt ein neues Array mit einer Funktion `onceWrapper` zurück, die eine Eigenschaft
// `listener` besitzt, welche den oben gebundenen Original-Listener enthält
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]

// Gibt "log once" auf der Konsole aus und hebt das `once`-Ereignis nicht auf
logFnWrapper.listener()

// Gibt "log once" auf der Konsole aus und entfernt den Listener
logFnWrapper()

emitter.on('log', () => console.log('log persistently'))
// Gibt ein neues Array mit einer einzelnen Funktion zurück, die oben durch `.on()` gebunden wurde
const newListeners = emitter.rawListeners('log')

// Gibt "log persistently" zweimal aus
newListeners[0]()
emitter.emit('log')
js
const EventEmitter = require('node:events')
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))

// Gibt ein neues Array mit einer Funktion `onceWrapper` zurück, die eine Eigenschaft
// `listener` besitzt, welche den oben gebundenen Original-Listener enthält
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]

// Gibt "log once" auf der Konsole aus und hebt das `once`-Ereignis nicht auf
logFnWrapper.listener()

// Gibt "log once" auf der Konsole aus und entfernt den Listener
logFnWrapper()

emitter.on('log', () => console.log('log persistently'))
// Gibt ein neues Array mit einer einzelnen Funktion zurück, die oben durch `.on()` gebunden wurde
const newListeners = emitter.rawListeners('log')

// Gibt "log persistently" zweimal aus
newListeners[0]()
emitter.emit('log')

emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])

[Verlauf]

VersionÄnderungen
v17.4.0, v16.14.0Nicht mehr experimentell.
v13.4.0, v12.16.0Hinzugefügt in: v13.4.0, v12.16.0

Die Methode Symbol.for('nodejs.rejection') wird aufgerufen, wenn eine Promise-Ablehnung beim Auslösen eines Ereignisses auftritt und captureRejections auf dem Emitter aktiviert ist. Es ist möglich, events.captureRejectionSymbol anstelle von Symbol.for('nodejs.rejection') zu verwenden.

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

class MyClass extends EventEmitter {
  constructor() {
    super({ captureRejections: true })
  }

  [captureRejectionSymbol](err, event, ...args) {
    console.log('rejection happened for', event, 'with', err, ...args)
    this.destroy(err)
  }

  destroy(err) {
    // Zerstöre die Ressource hier.
  }
}
js
const { EventEmitter, captureRejectionSymbol } = require('node:events')

class MyClass extends EventEmitter {
  constructor() {
    super({ captureRejections: true })
  }

  [captureRejectionSymbol](err, event, ...args) {
    console.log('rejection happened for', event, 'with', err, ...args)
    this.destroy(err)
  }

  destroy(err) {
    // Zerstöre die Ressource hier.
  }
}

events.defaultMaxListeners

Hinzugefügt in: v0.11.2

Standardmäßig können maximal 10 Listener für ein einzelnes Ereignis registriert werden. Diese Grenze kann für einzelne EventEmitter-Instanzen mit der Methode emitter.setMaxListeners(n) geändert werden. Um den Standard für alle EventEmitter-Instanzen zu ändern, kann die Eigenschaft events.defaultMaxListeners verwendet werden. Wenn dieser Wert keine positive Zahl ist, wird ein RangeError ausgelöst.

Seien Sie vorsichtig beim Setzen von events.defaultMaxListeners, da die Änderung alle EventEmitter-Instanzen betrifft, einschließlich derer, die vor der Änderung erstellt wurden. Der Aufruf von emitter.setMaxListeners(n) hat jedoch weiterhin Vorrang vor events.defaultMaxListeners.

Dies ist keine harte Grenze. Die EventEmitter-Instanz erlaubt das Hinzufügen weiterer Listener, gibt aber eine Warnung an stderr aus, die darauf hinweist, dass ein "mögliches EventEmitter-Speicherleck" entdeckt wurde. Für jede einzelne EventEmitter können die Methoden emitter.getMaxListeners() und emitter.setMaxListeners() verwendet werden, um diese Warnung vorübergehend zu vermeiden:

defaultMaxListeners hat keinen Einfluss auf AbortSignal-Instanzen. Während es immer noch möglich ist, emitter.setMaxListeners(n) zu verwenden, um eine Warnungsbeschränkung für einzelne AbortSignal-Instanzen festzulegen, geben AbortSignal-Instanzen standardmäßig keine Warnung aus.

js
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.setMaxListeners(emitter.getMaxListeners() + 1)
emitter.once('event', () => {
  // mache etwas
  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', () => {
  // mache etwas
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0))
})

Das Kommandozeilenflag --trace-warnings kann verwendet werden, um die Stack-Trace für solche Warnungen anzuzeigen.

Die ausgegebene Warnung kann mit process.on('warning') geprüft werden und enthält die zusätzlichen Eigenschaften emitter, type und count, die sich auf die Event-Emitter-Instanz, den Ereignisnamen und die Anzahl der angehängten Listener beziehen. Ihre name-Eigenschaft ist auf 'MaxListenersExceededWarning' gesetzt.

events.errorMonitor

Hinzugefügt in: v13.6.0, v12.17.0

Dieses Symbol dient zum Installieren eines Listeners, der nur 'error'-Ereignisse überwacht. Listener, die mit diesem Symbol installiert werden, werden aufgerufen, bevor die regulären 'error'-Listener aufgerufen werden.

Die Installation eines Listeners mit diesem Symbol ändert das Verhalten nicht, sobald ein 'error'-Ereignis emittiert wird. Daher stürzt der Prozess weiterhin ab, wenn kein regulärer 'error'-Listener installiert ist.

events.getEventListeners(emitterOrTarget, eventName)

Hinzugefügt in: v15.2.0, v14.17.0

Gibt eine Kopie des Arrays der Listener für das Ereignis mit dem Namen eventName zurück.

Für EventEmitters verhält sich dies genau wie der Aufruf von .listeners auf dem Emitter.

Für EventTargets ist dies die einzige Möglichkeit, die Ereignislistener für das Event-Target zu erhalten. Dies ist nützlich für Debugging- und Diagnosezwecke.

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)

Hinzugefügt in: v19.9.0, v18.17.0

Gibt die aktuell festgelegte maximale Anzahl von Listenern zurück.

Für EventEmitters verhält sich dies genau so, als würde .getMaxListeners auf den Emitter aufgerufen.

Für EventTargets ist dies die einzige Möglichkeit, die maximale Anzahl von Event-Listenern für das Event-Target zu erhalten. Wenn die Anzahl der Ereignishandler für ein einzelnes EventTarget die festgelegte maximale Anzahl überschreitet, gibt das EventTarget eine Warnung aus.

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

[Verlauf]

VersionÄnderungen
v15.0.0Die Option signal wird jetzt unterstützt.
v11.13.0, v10.16.0Hinzugefügt in: v11.13.0, v10.16.0

Erstellt ein Promise, das erfüllt wird, wenn der EventEmitter das angegebene Ereignis auslöst, oder das abgelehnt wird, wenn der EventEmitter während des Wartens 'error' auslöst. Das Promise wird mit einem Array aller Argumente aufgelöst, die an das angegebene Ereignis gesendet wurden.

Diese Methode ist absichtlich generisch und funktioniert mit der Web-Plattform-Schnittstelle EventTarget, die keine spezielle Semantik für das Ereignis 'error' hat und nicht auf das Ereignis 'error' hört.

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

Die spezielle Behandlung des Ereignisses 'error' wird nur verwendet, wenn events.once() verwendet wird, um auf ein anderes Ereignis zu warten. Wenn events.once() verwendet wird, um auf das Ereignis 'error' selbst zu warten, wird es wie jede andere Art von Ereignis ohne spezielle Behandlung behandelt:

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

// Gibt aus: 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'))

// Gibt aus: ok boom

Ein <AbortSignal> kann verwendet werden, um das Warten auf das Ereignis abzubrechen:

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() // Gibt aus: 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() // Gibt aus: Waiting for the event was canceled!

Warten auf mehrere Ereignisse, die auf process.nextTick() emittiert werden

Es gibt einen Randfall, der beachtet werden sollte, wenn die Funktion events.once() verwendet wird, um auf mehrere Ereignisse zu warten, die in derselben Batch-Operation von process.nextTick() oder immer dann emittiert werden, wenn mehrere Ereignisse synchron emittiert werden. Da die process.nextTick()-Warteschlange vor der Microtask-Warteschlange von Promise geleert wird und EventEmitter alle Ereignisse synchron emittiert, kann es vorkommen, dass events.once() ein Ereignis verpasst.

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

  // Dieses Promise wird sich nie auflösen, da das Ereignis 'foo' bereits emittiert wurde, bevor das Promise erstellt wurde.
  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')

  // Dieses Promise wird sich nie auflösen, da das Ereignis 'foo' bereits emittiert wurde, bevor das Promise erstellt wurde.
  await once(myEE, 'foo')
  console.log('foo')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))

Um beide Ereignisse abzufangen, erstellen Sie jedes der Promises, bevor Sie auf eines von ihnen warten. Dann ist es möglich, Promise.all(), Promise.race() oder Promise.allSettled() zu verwenden:

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

[Versionsverlauf]

VersionÄnderungen
v17.4.0, v16.14.0Nicht mehr experimentell.
v13.4.0, v12.16.0Hinzugefügt in: v13.4.0, v12.16.0

Wert: <boolean>

Ändert die Standardoption captureRejections für alle neuen EventEmitter-Objekte.

events.captureRejectionSymbol

[Versionsverlauf]

VersionÄnderungen
v17.4.0, v16.14.0Nicht mehr experimentell.
v13.4.0, v12.16.0Hinzugefügt in: v13.4.0, v12.16.0

Wert: Symbol.for('nodejs.rejection')

Siehe, wie man einen benutzerdefinierten Rejection-Handler schreibt.

events.listenerCount(emitter, eventName)

Hinzugefügt in: v0.9.12

Veraltet seit: v3.2.0

[Stabil: 0 - Veraltet]

Stabil: 0 Stabilität: 0 - Veraltet: Verwenden Sie stattdessen emitter.listenerCount().

Eine Klassenmethode, die die Anzahl der Listener für den angegebenen eventName zurückgibt, die auf dem angegebenen emitter registriert sind.

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

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Gibt aus: 2
js
const { EventEmitter, listenerCount } = require('node:events')

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// Gibt aus: 2

events.on(emitter, eventName[, options])

[Versionsgeschichte]

VersionÄnderungen
v22.0.0, v20.13.0Unterstützung der Optionen highWaterMark und lowWaterMark, aus Gründen der Konsistenz. Alte Optionen werden weiterhin unterstützt.
v20.0.0Die Optionen close, highWatermark und lowWatermark werden jetzt unterstützt.
v13.6.0, v12.16.0Hinzugefügt in: v13.6.0, v12.16.0
  • emitter <EventEmitter>

  • eventName <string> | <symbol> Der Name des Ereignisses, auf das gewartet wird

  • options <Object>

    • signal <AbortSignal> Kann verwendet werden, um das Warten auf Ereignisse abzubrechen.
    • close - <string[]> Namen von Ereignissen, die die Iteration beenden.
    • highWaterMark - <integer> Standardwert: Number.MAX_SAFE_INTEGER Die obere Wassermarke. Der Emitter wird jedes Mal angehalten, wenn die Größe der gepufferten Ereignisse höher ist. Nur unterstützt bei Emittern, die die Methoden pause() und resume() implementieren.
    • lowWaterMark - <integer> Standardwert: 1 Die untere Wassermarke. Der Emitter wird jedes Mal fortgesetzt, wenn die Größe der gepufferten Ereignisse niedriger ist. Nur unterstützt bei Emittern, die die Methoden pause() und resume() implementieren.
  • Rückgabewert: <AsyncIterator>, der eventName-Ereignisse iteriert, die vom emitter emittiert werden

js
import { on, EventEmitter } from 'node:events'
import process from 'node:process'

const ee = new EventEmitter()

// Später emittieren
process.nextTick(() => {
  ee.emit('foo', 'bar')
  ee.emit('foo', 42)
})

for await (const event of on(ee, 'foo')) {
  // Die Ausführung dieses inneren Blocks ist synchron und verarbeitet
  // ein Ereignis nach dem anderen (auch mit await). Nicht verwenden,
  // wenn eine gleichzeitige Ausführung erforderlich ist.
  console.log(event) // gibt ['bar'] [42] aus
}
// Hier unerreichbar
js
const { on, EventEmitter } = require('node:events')

;(async () => {
  const ee = new EventEmitter()

  // Später emittieren
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const event of on(ee, 'foo')) {
    // Die Ausführung dieses inneren Blocks ist synchron und verarbeitet
    // ein Ereignis nach dem anderen (auch mit await). Nicht verwenden,
    // wenn eine gleichzeitige Ausführung erforderlich ist.
    console.log(event) // gibt ['bar'] [42] aus
  }
  // Hier unerreichbar
})()

Gibt einen AsyncIterator zurück, der eventName-Ereignisse iteriert. Es wird ein Fehler ausgelöst, wenn der EventEmitter 'error' emittiert. Es entfernt alle Listener beim Verlassen der Schleife. Der value, der von jeder Iteration zurückgegeben wird, ist ein Array, das aus den emittierten Ereignisargumenten besteht.

Ein <AbortSignal> kann verwendet werden, um das Warten auf Ereignisse abzubrechen:

js
import { on, EventEmitter } from 'node:events'
import process from 'node:process'

const ac = new AbortController()

;(async () => {
  const ee = new EventEmitter()

  // Später emittieren
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
    // Die Ausführung dieses inneren Blocks ist synchron und verarbeitet
    // ein Ereignis nach dem anderen (auch mit await). Nicht verwenden,
    // wenn eine gleichzeitige Ausführung erforderlich ist.
    console.log(event) // gibt ['bar'] [42] aus
  }
  // Hier unerreichbar
})()

process.nextTick(() => ac.abort())
js
const { on, EventEmitter } = require('node:events')

const ac = new AbortController()

;(async () => {
  const ee = new EventEmitter()

  // Später emittieren
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
    // Die Ausführung dieses inneren Blocks ist synchron und verarbeitet
    // ein Ereignis nach dem anderen (auch mit await). Nicht verwenden,
    // wenn eine gleichzeitige Ausführung erforderlich ist.
    console.log(event) // gibt ['bar'] [42] aus
  }
  // Hier unerreichbar
})()

process.nextTick(() => ac.abort())

events.setMaxListeners(n[, ...eventTargets])

Hinzugefügt in: 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)

Hinzugefügt in: v20.5.0, v18.18.0

[Stabil: 1 - Experimentell]

Stabil: 1 Stabilität: 1 - Experimentell

Hört einmalig auf das abort-Ereignis des angegebenen signal.

Das Abhören des abort-Ereignisses bei Abbruchsignalen ist unsicher und kann zu Ressourcenlecks führen, da eine andere Drittpartei mit dem Signal e.stopImmediatePropagation() aufrufen kann. Node.js kann dies leider nicht ändern, da dies gegen den Webstandard verstoßen würde. Darüber hinaus macht die ursprüngliche API es leicht, das Entfernen von Listenern zu vergessen.

Diese API ermöglicht die sichere Verwendung von AbortSignals in Node.js-APIs, indem sie diese beiden Probleme löst, indem sie das Ereignis so abhört, dass stopImmediatePropagation die Ausführung des Listeners nicht verhindert.

Gibt ein Disposable zurück, damit es einfacher abgemeldet werden kann.

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

Klasse: events.EventEmitterAsyncResource extends EventEmitter

Hinzugefügt in: v17.4.0, v16.14.0

Integriert EventEmitter mit <AsyncResource> für EventEmitters, die eine manuelle asynchrone Nachverfolgung benötigen. Konkret werden alle von Instanzen von events.EventEmitterAsyncResource emittierten Ereignisse innerhalb ihres asynchronen Kontexts ausgeführt.

js
import { EventEmitterAsyncResource, EventEmitter } from 'node:events'
import { notStrictEqual, strictEqual } from 'node:assert'
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks'

// Async-Tracking-Tools identifizieren dies als 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' })

// 'foo'-Listener werden im asynchronen Kontext des EventEmitter ausgeführt.
ee1.on('foo', () => {
  strictEqual(executionAsyncId(), ee1.asyncId)
  strictEqual(triggerAsyncId(), ee1.triggerAsyncId)
})

const ee2 = new EventEmitter()

// 'foo'-Listener auf gewöhnlichen EventEmittern, die keinen asynchronen
// Kontext verfolgen, werden jedoch im selben asynchronen Kontext wie das emit() ausgeführt.
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')

// Async-Tracking-Tools identifizieren dies als 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' })

// 'foo'-Listener werden im asynchronen Kontext des EventEmitter ausgeführt.
ee1.on('foo', () => {
  strictEqual(executionAsyncId(), ee1.asyncId)
  strictEqual(triggerAsyncId(), ee1.triggerAsyncId)
})

const ee2 = new EventEmitter()

// 'foo'-Listener auf gewöhnlichen EventEmittern, die keinen asynchronen
// Kontext verfolgen, werden jedoch im selben asynchronen Kontext wie das emit() ausgeführt.
ee2.on('foo', () => {
  notStrictEqual(executionAsyncId(), ee2.asyncId)
  notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId)
})

Promise.resolve().then(() => {
  ee1.emit('foo')
  ee2.emit('foo')
})

Die Klasse EventEmitterAsyncResource verfügt über die gleichen Methoden und akzeptiert die gleichen Optionen wie EventEmitter und AsyncResource selbst.

new events.EventEmitterAsyncResource([options])

  • options <Objekt>
    • captureRejections <boolean> Aktiviert die automatische Erfassung von Promise-Ablehnungen. Standardwert: false.
    • name <string> Der Typ des asynchronen Ereignisses. Standardwert: new.target.name.
    • triggerAsyncId <number> Die ID des Ausführungskontexts, der dieses asynchrone Ereignis erstellt hat. Standardwert: executionAsyncId().
    • requireManualDestroy <boolean> Wenn auf true gesetzt, deaktiviert emitDestroy, wenn das Objekt durch Garbage Collection freigegeben wird. Dies muss normalerweise nicht gesetzt werden (auch wenn emitDestroy manuell aufgerufen wird), es sei denn, die asyncId der Ressource wird abgerufen und die emitDestroy der sensiblen API wird damit aufgerufen. Wenn auf false gesetzt, findet der emitDestroy-Aufruf bei Garbage Collection nur statt, wenn mindestens ein aktiver destroy-Hook vorhanden ist. Standardwert: false.

eventemitterasyncresource.asyncId

  • Typ: <number> Die eindeutige asyncId, die der Ressource zugewiesen ist.

eventemitterasyncresource.asyncResource

Das zurückgegebene AsyncResource-Objekt hat eine zusätzliche eventEmitter-Eigenschaft, die einen Verweis auf diese EventEmitterAsyncResource bereitstellt.

eventemitterasyncresource.emitDestroy()

Ruft alle destroy-Hooks auf. Dies sollte nur einmal aufgerufen werden. Ein Fehler wird ausgelöst, wenn es mehr als einmal aufgerufen wird. Dies muss manuell aufgerufen werden. Wenn die Ressource von der GC gesammelt wird, werden die destroy-Hooks niemals aufgerufen.

eventemitterasyncresource.triggerAsyncId

  • Typ: <number> Die gleiche triggerAsyncId, die an den AsyncResource-Konstruktor übergeben wird.

EventTarget und Event API

[Verlauf]

VersionÄnderungen
v16.0.0Änderung der EventTarget-Fehlerbehandlung.
v15.4.0Nicht mehr experimentell.
v15.0.0Die Klassen EventTarget und Event sind jetzt als globale Variablen verfügbar.
v14.5.0Hinzugefügt in: v14.5.0

Die Objekte EventTarget und Event sind eine Node.js-spezifische Implementierung der EventTarget Web API, die von einigen Node.js-Kern-APIs bereitgestellt werden.

js
const target = new EventTarget()

target.addEventListener('foo', event => {
  console.log('foo event happened!')
})

Node.js EventTarget vs. DOM EventTarget

Es gibt zwei Hauptunterschiede zwischen dem Node.js EventTarget und der EventTarget Web API:

NodeEventTarget vs. EventEmitter

Das NodeEventTarget-Objekt implementiert eine modifizierte Teilmenge der EventEmitter-API, die es ermöglicht, in bestimmten Situationen einen EventEmitter eng zu emulieren. Ein NodeEventTarget ist kein Instanz von EventEmitter und kann in den meisten Fällen nicht anstelle eines EventEmitter verwendet werden.

Ereignislistener

Ereignislistener, die für einen Ereignistyp type registriert sind, können entweder JavaScript-Funktionen oder Objekte mit einer handleEvent-Eigenschaft sein, deren Wert eine Funktion ist.

In beiden Fällen wird die Handler-Funktion mit dem event-Argument aufgerufen, das an die Funktion eventTarget.dispatchEvent() übergeben wird.

Asynchrone Funktionen können als Ereignislistener verwendet werden. Wenn eine asynchrone Handler-Funktion zurückgewiesen wird, wird die Zurückweisung erfasst und wie in EventTarget-Fehlerbehandlung beschrieben behandelt.

Ein Fehler, der von einer Handler-Funktion ausgelöst wird, verhindert nicht, dass die anderen Handler aufgerufen werden.

Der Rückgabewert einer Handler-Funktion wird ignoriert.

Handler werden immer in der Reihenfolge aufgerufen, in der sie hinzugefügt wurden.

Handler-Funktionen können das event-Objekt verändern.

js
function handler1(event) {
  console.log(event.type) // Gibt 'foo' aus
  event.a = 1
}

async function handler2(event) {
  console.log(event.type) // Gibt 'foo' aus
  console.log(event.a) // Gibt 1 aus
}

const handler3 = {
  handleEvent(event) {
    console.log(event.type) // Gibt 'foo' aus
  },
}

const handler4 = {
  async handleEvent(event) {
    console.log(event.type) // Gibt 'foo' aus
  },
}

const target = new EventTarget()

target.addEventListener('foo', handler1)
target.addEventListener('foo', handler2)
target.addEventListener('foo', handler3)
target.addEventListener('foo', handler4, { once: true })

EventTarget Fehlerbehandlung

Wenn ein registrierter Ereignislistener einen Fehler auslöst (oder ein Promise zurückgibt, das abgelehnt wird), wird der Fehler standardmäßig als nicht abgefangene Ausnahme auf process.nextTick() behandelt. Das bedeutet, dass nicht abgefangene Ausnahmen in EventTargets standardmäßig den Node.js-Prozess beenden.

Das Auslösen eines Fehlers innerhalb eines Ereignislisteners verhindert nicht, dass die anderen registrierten Handler aufgerufen werden.

Der EventTarget implementiert keine spezielle Standardbehandlung für Ereignisse vom Typ 'error' wie EventEmitter.

Derzeit werden Fehler zuerst an das process.on('error')-Ereignis weitergeleitet, bevor sie process.on('uncaughtException') erreichen. Dieses Verhalten ist veraltet und wird in einer zukünftigen Version geändert, um EventTarget an andere Node.js-APIs anzupassen. Jeder Code, der sich auf das Ereignis process.on('error') stützt, sollte an das neue Verhalten angepasst werden.

Klasse: Event

[Verlauf]

VersionÄnderungen
v15.0.0Die Event-Klasse ist jetzt über das globale Objekt verfügbar.
v14.5.0Hinzugefügt in: v14.5.0

Das Event-Objekt ist eine Adaption der Event Web API. Instanzen werden intern von Node.js erstellt.

event.bubbles

Hinzugefügt in: v14.5.0

Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.cancelBubble

Hinzugefügt in: v14.5.0

[Stabil: 3 - Veraltet]

Stabil: 3 Stabilität: 3 - Veraltet: Verwenden Sie stattdessen event.stopPropagation().

Alias für event.stopPropagation(), wenn auf true gesetzt. Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.cancelable

Hinzugefügt in: v14.5.0

  • Typ: <boolean> Wahr, wenn das Ereignis mit der Option cancelable erstellt wurde.

event.composed

Hinzugefügt in: v14.5.0

Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.composedPath()

Hinzugefügt in: v14.5.0

Gibt ein Array zurück, das das aktuelle EventTarget als einzigen Eintrag enthält, oder ist leer, wenn das Ereignis nicht ausgelöst wird. Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.currentTarget

Hinzugefügt in: v14.5.0

Alias für event.target.

event.defaultPrevented

Hinzugefügt in: v14.5.0

Ist true, wenn cancelable true ist und event.preventDefault() aufgerufen wurde.

event.eventPhase

Hinzugefügt in: v14.5.0

  • Typ: <number> Gibt 0 zurück, während ein Ereignis nicht ausgelöst wird, 2, während es ausgelöst wird.

Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.initEvent(type[, bubbles[, cancelable]])

Hinzugefügt in: v19.5.0

[Stabil: 3 - Veraltet]

Stabil: 3 Stabilität: 3 - Veraltet: Die WHATWG-Spezifikation betrachtet es als veraltet, und Benutzer sollten es überhaupt nicht verwenden.

Redundant mit Ereigniskonstruktoren und nicht in der Lage, composed zu setzen. Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.isTrusted

Hinzugefügt in: v14.5.0

Das <AbortSignal> "abort"-Ereignis wird mit isTrusted auf true gesetzt ausgelöst. Der Wert ist in allen anderen Fällen false.

event.preventDefault()

Hinzugefügt in: v14.5.0

Setzt die Eigenschaft defaultPrevented auf true, wenn cancelable true ist.

event.returnValue

Hinzugefügt in: v14.5.0

[Stabil: 3 - Veraltet]

Stabil: 3 Stabilität: 3 - Veraltet: Verwenden Sie stattdessen event.defaultPrevented.

  • Typ: <boolean> True, wenn das Ereignis nicht abgebrochen wurde.

Der Wert von event.returnValue ist immer das Gegenteil von event.defaultPrevented. Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.srcElement

Hinzugefügt in: v14.5.0

[Stabil: 3 - Veraltet]

Stabil: 3 Stabilität: 3 - Veraltet: Verwenden Sie stattdessen event.target.

Alias für event.target.

event.stopImmediatePropagation()

Hinzugefügt in: v14.5.0

Stoppt die Ausführung von Ereignis-Listenern, nachdem der aktuelle abgeschlossen ist.

event.stopPropagation()

Hinzugefügt in: v14.5.0

Dies wird in Node.js nicht verwendet und wird nur der Vollständigkeit halber bereitgestellt.

event.target

Hinzugefügt in: v14.5.0

event.timeStamp

Hinzugefügt in: v14.5.0

Der Zeitstempel in Millisekunden, als das Event-Objekt erstellt wurde.

event.type

Hinzugefügt in: v14.5.0

Die Ereignistypkennung.

Klasse: EventTarget

[Verlauf]

VersionÄnderungen
v15.0.0Die Klasse EventTarget ist jetzt über das globale Objekt verfügbar.
v14.5.0Hinzugefügt in: v14.5.0

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

[Verlauf]

VersionÄnderungen
v15.4.0Unterstützung für die Option signal hinzugefügt.
v14.5.0Hinzugefügt in: v14.5.0
  • type <string>
  • listener <Function> | <EventListener>
  • options <Object>
    • once <boolean> Wenn true, wird der Listener automatisch entfernt, wenn er zum ersten Mal aufgerufen wird. Standard: false.
    • passive <boolean> Wenn true, dient dies als Hinweis darauf, dass der Listener die Methode preventDefault() des Event-Objekts nicht aufrufen wird. Standard: false.
    • capture <boolean> Wird von Node.js nicht direkt verwendet. Zur API-Vollständigkeit hinzugefügt. Standard: false.
    • signal <AbortSignal> Der Listener wird entfernt, wenn die Methode abort() des gegebenen AbortSignal-Objekts aufgerufen wird.

Fügt einen neuen Handler für das Ereignis type hinzu. Jeder gegebene listener wird nur einmal pro type und pro Wert der Option capture hinzugefügt.

Wenn die Option once auf true gesetzt ist, wird der listener nach dem nächsten Versand eines Ereignisses vom Typ type entfernt.

Die Option capture wird von Node.js nicht funktional verwendet, außer zur Verfolgung registrierter Ereignislistener gemäß der EventTarget-Spezifikation. Konkret wird die Option capture als Teil des Schlüssels verwendet, wenn ein listener registriert wird. Jeder einzelne listener kann einmal mit capture = false und einmal mit capture = true hinzugefügt werden.

js
function handler(event) {}

const target = new EventTarget()
target.addEventListener('foo', handler, { capture: true }) // erster
target.addEventListener('foo', handler, { capture: false }) // zweiter

// Entfernt die zweite Instanz von handler
target.removeEventListener('foo', handler)

// Entfernt die erste Instanz von handler
target.removeEventListener('foo', handler, { capture: true })

eventTarget.dispatchEvent(event)

Hinzugefügt in: v14.5.0

  • event <Event>
  • Rückgabewert: <boolean> true, wenn entweder der Wert des cancelable-Attributs des Ereignisses false ist oder seine Methode preventDefault() nicht aufgerufen wurde, andernfalls false.

Sendet das event an die Liste der Handler für event.type.

Die registrierten Ereignislistener werden synchron in der Reihenfolge ihres Registrierens aufgerufen.

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

Hinzugefügt in: v14.5.0

Entfernt den listener aus der Liste der Handler für das Ereignis type.

Klasse: CustomEvent

[Verlauf]

VersionÄnderungen
v23.0.0Nicht mehr experimentell.
v22.1.0, v20.13.0CustomEvent ist jetzt stabil.
v19.0.0Nicht mehr hinter dem --experimental-global-customevent CLI-Flag.
v18.7.0, v16.17.0Hinzugefügt in: v18.7.0, v16.17.0

[Stabil: 2 - Stabil]

Stabil: 2 Stabilität: 2 - Stabil

Das CustomEvent-Objekt ist eine Adaption der CustomEvent Web API. Instanzen werden intern von Node.js erstellt.

event.detail

[Verlauf]

VersionÄnderungen
v22.1.0, v20.13.0CustomEvent ist jetzt stabil.
v18.7.0, v16.17.0Hinzugefügt in: v18.7.0, v16.17.0

[Stabil: 2 - Stabil]

Stabil: 2 Stabilität: 2 - Stabil

  • Typ: <any> Gibt benutzerdefinierte Daten zurück, die bei der Initialisierung übergeben wurden.

Schreibgeschützt.

Klasse: NodeEventTarget

Hinzugefügt in: v14.5.0

NodeEventTarget ist eine Node.js-spezifische Erweiterung von EventTarget, die eine Teilmenge der EventEmitter-API emuliert.

nodeEventTarget.addListener(type, listener)

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die die äquivalente EventEmitter-API emuliert. Der einzige Unterschied zwischen addListener() und addEventListener() besteht darin, dass addListener() eine Referenz auf das EventTarget zurückgibt.

nodeEventTarget.emit(type, arg)

Hinzugefügt in: v15.2.0

  • type <string>
  • arg <any>
  • Gibt zurück: <boolean> true, wenn Event-Listener für den type registriert sind, andernfalls false.

Node.js-spezifische Erweiterung der EventTarget-Klasse, die das arg an die Liste der Handler für type verteilt.

nodeEventTarget.eventNames()

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die ein Array von Ereignisnamen type zurückgibt, für die Event-Listener registriert sind.

nodeEventTarget.listenerCount(type)

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die die Anzahl der für den type registrierten Event-Listener zurückgibt.

nodeEventTarget.setMaxListeners(n)

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die die maximale Anzahl an Event-Listenern auf n setzt.

nodeEventTarget.getMaxListeners()

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die die maximale Anzahl an Event-Listenern zurückgibt.

nodeEventTarget.off(type, listener[, options])

Hinzugefügt in: v14.5.0

Node.js-spezifisches Alias für eventTarget.removeEventListener().

nodeEventTarget.on(type, listener)

Hinzugefügt in: v14.5.0

Node.js-spezifisches Alias für eventTarget.addEventListener().

nodeEventTarget.once(type, listener)

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die einen once-Listener für den angegebenen Event-Typ type hinzufügt. Dies entspricht dem Aufruf von on mit der auf true gesetzten once-Option.

nodeEventTarget.removeAllListeners([type])

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse. Wenn type angegeben ist, werden alle registrierten Listener für type entfernt, andernfalls werden alle registrierten Listener entfernt.

nodeEventTarget.removeListener(type, listener[, options])

Hinzugefügt in: v14.5.0

Node.js-spezifische Erweiterung der EventTarget-Klasse, die den listener für den gegebenen type entfernt. Der einzige Unterschied zwischen removeListener() und removeEventListener() besteht darin, dass removeListener() eine Referenz auf das EventTarget zurückgibt.