diff --git a/doc/api/events.md b/doc/api/events.md index 778c97bfb483e7..e3bcf73ba2aae8 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -1799,6 +1799,64 @@ const emitter = new EventEmitter(); setMaxListeners(5, target, emitter); ``` +## `events.addAbortListener(signal, resource)` + + + +> Stability: 1 - Experimental + +* `signal` {AbortSignal} +* `listener` {Function|EventListener} +* Returns: {Disposable} that removes the `abort` listener. + +Listens once to the `abort` event on the provided `signal`. + +Listening to the `abort` event on abort signals is unsafe and may +lead to resource leaks since another third party with the signal can +call [`e.stopImmediatePropagation()`][]. Unfortunately Node.js cannot change +this since it would violate the web standard. Additionally, the original +API makes it easy to forget to remove listeners. + +This API allows safely using `AbortSignal`s in Node.js APIs by solving these +two issues by listening to the event such that `stopImmediatePropagation` does +not prevent the listener from running. + +Returns a disposable so that it may be unsubscribed from more easily. + +```cjs +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](); + } +} +``` + +```mjs +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](); + } +} +``` + ## Class: `events.EventEmitterAsyncResource extends EventEmitter`