EventEmitter
Node's classic EventEmitter, imported from events (it is no global), not the WHATWG EventTarget/Event trio. With no type argument every event takes any arguments, @types/node's default event map; a type argument is an event map of argument tuples. The on/once/emit/off surface is compiled by the compiler rather than a registered class, so instanceof answers as a compile-time constant, and every listener is held as a dynamic function. A subclass can still override any of those methods (the override wins at every call site, and super.<method>(...) reaches the built-in).
new EventEmitter<T>() / class X extends EventEmitter<T>
Works, with caveatsEither construct a standalone emitter or root a class in one via extends — the subclass then gets the whole on/once/emit/off/removeListener/removeAllListeners/listenerCount/eventNames surface for free, and its constructor calls super(). With no T every event takes any arguments; T is an event map of argument tuples (`{ data: [chunk: string]; end: [] }`).
ReturnsEventEmitter<T> — An emitter, or a subclass instance rooted in one.
import { EventEmitter } from 'events';
class Downloader extends EventEmitter {
progress(chunk: number): void {
this.emit("progress", this.name + ": " + this.bytesDone + " bytes");
}
}
const bus = new EventEmitter();- A subclass may override any EventEmitter method (
on/once/emit/off/removeListener/removeAllListeners/listenerCount/eventNames) — the override wins at every call site (statically and virtually), andsuper.<method>(...)reaches the nearest ancestor override or the built-in dispatch. The override's declared signature isn't checked against the built-in it replaces - The type checker treats every event as taking any arguments; a typed map's event names and argument types are checked by code generation instead
- Constructor options (
captureRejections) are rejected
.on(event, listener) / .once(event, listener)
ExactRegisters a listener for an event; once fires at most once then detaches itself. Both are chainable, returning the emitter. A listener may take fewer parameters than the event passes: one it isn't passed is undefined or its default.
Parameters- eventstring
- Event name (a string literal for a map-typed emitter).
- listener(...args) => void
- Callback whose params match the event's payload type.
this — The emitter, for chaining.
dl.on("progress", (msg: string): void => {
console.log(msg);
});
dl.once("complete", (name: string): void => {
console.log("done: " + name);
});- A **tuple** payload
[A, B, …]is Node's multi-argument event — the listener takes one parameter per element ((a, b) => …); a non-tuple payload is a single argument (or none, forvoid). No open-ended(...args)beyond a declared tuple - A map-typed emitter requires a string-literal event name at every call site
.emit(event, ...args)
ExactSynchronously invokes every listener registered for event, in registration order, with the emitter as this, passing along the arguments. Returns whether any listener ran.
Parameters- eventstring
- Event name (a string literal for a map-typed emitter).
- args...
- The event's arguments.
boolean — true if at least one listener ran.
this.emit("progress", 512, 1024);
this.emit("done", "/tmp/file.bin");- A map-typed emitter requires a string-literal event name
.off / .removeListener / .removeAllListeners
ExactDetaches listeners. off and removeListener remove the most recently added matching listener, keeping the rest in order. removeAllListeners with no argument clears every event; passed an event name, it clears just that one.
Parameters- eventstring
- Event name; omitted on removeAllListeners to clear all.
- listener(...args) => void
- The exact listener reference to remove.
this — The emitter, for chaining.
bus.on("tick", onTick);
bus.off("tick", onTick);
bus.emit("tick", 2); // (no listener left — no output).addListener / .prependListener / .prependOnceListener
ExactaddListener is on under its other name. prependListener adds the listener before the ones already registered, so it runs first; prependOnceListener does the same for a one-shot listener.
Parameters- eventstring
- Event name.
- listener(...args) => void
- The function to call.
this — The emitter, for chaining.
bus.on("tick", () => console.log("second"));
bus.prependListener("tick", () => console.log("first"));
bus.emit("tick");- A map-typed emitter requires a string-literal event name
.listenerCount(event) / .eventNames()
ExactlistenerCount reports how many listeners are registered for an event. eventNames returns the names that currently have listeners, string names in registration order and then symbol names; an event whose last listener is removed drops out.
Parameters- eventstring | symbol
- Event name to count (listenerCount only).
number | (string | symbol)[] — The listener count, or the array of event names.
console.log(bus.listenerCount("tick")); // 0
console.log(dl.listenerCount("progress")); // 1emit('error', ...) special-case
ExactMatches Node's one specially treated event name: emitting 'error' with no registered 'error' listener throws — the argument itself when it is an Error, otherwise an Error reading "Unhandled error. (<value>)", the value rendered by util.inspect.
Returnsboolean — As emit — but throws when 'error' has no listener.
try {
dl.emit("error", "disk full");
} catch (e) {
console.log("caught: " + e.message); // caught: Unhandled error. ('disk full')
}- A non-Error, non-string argument is rendered with
String()in the message, where Node usesutil.inspect
events.once()
ExactReturns a Promise that resolves with the event's argument array the first time it fires; an 'error' first rejects it, and an AbortSignal option cancels it.
Parameters- emitterEventEmitter
- The emitter to observe.
- namestring
- The event name.
Promise<args[]> — Resolves with the event's arguments.
import { EventEmitter, once } from 'events'
const ee = new EventEmitter<{ ready: [number] }>()
setTimeout(() => { ee.emit('ready', 42) }, 0)
const arr = await once(ee, 'ready') // [42]- Single-value / homogeneous multi-arg events only (mixed-type tuples rejected)
events.on()
ExactAn async iterator yielding each emission's argument array (for await (const [x] of on(ee, 'data'))), buffering events between iterations; leaving the loop removes its listeners.
Parameters- emitterEventEmitter
- The emitter to observe.
- namestring
- Callback taking the event's arguments.
AsyncIterableIterator<args[]> — An async iterator yielding each emission's argument array.
import { EventEmitter, on } from 'events'
const ee = new EventEmitter<{ tick: [number] }>()
setTimeout(() => { ee.emit('tick', 1); ee.emit('tick', 2) }, 0)
for await (const [n] of on(ee, 'tick')) {
console.log(n)
if (n >= 2) break
}- A map-typed emitter requires a string-literal event name at every call site