From 74ca960aac4600953caacd5f250b11a90bd70ee7 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 22 May 2020 18:11:14 -0700 Subject: [PATCH] lib: initial experimental AbortController implementation AbortController impl based very closely on: https://github.com/mysticatea/abort-controller Marked experimental. Not currently used by any of the existing promise apis. Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/33527 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Matteo Collina Reviewed-By: Anna Henningsen --- .eslintrc.js | 1 + doc/api/cli.md | 8 +++ doc/api/globals.md | 96 +++++++++++++++++++++++++ doc/node.1 | 3 + lib/internal/abort_controller.js | 83 +++++++++++++++++++++ lib/internal/bootstrap/pre_execution.js | 27 +++++++ lib/internal/main/worker_thread.js | 2 + node.gyp | 1 + src/node_options.cc | 4 ++ src/node_options.h | 1 + test/common/index.js | 1 + test/parallel/test-abortcontroller.js | 22 ++++++ test/parallel/test-bootstrap-modules.js | 7 ++ tools/doc/type-parser.js | 4 ++ 14 files changed, 260 insertions(+) create mode 100644 lib/internal/abort_controller.js create mode 100644 test/parallel/test-abortcontroller.js diff --git a/.eslintrc.js b/.eslintrc.js index 8279dfc9c4ab41..8542d2e77e0ea6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -280,6 +280,7 @@ module.exports = { 'node-core/no-duplicate-requires': 'error', }, globals: { + AbortController: 'readable', Atomics: 'readable', BigInt: 'readable', BigInt64Array: 'readable', diff --git a/doc/api/cli.md b/doc/api/cli.md index 46c2cad5e88a8b..7e317c10c2518a 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -167,6 +167,13 @@ Enable experimental Source Map V3 support for stack traces. Currently, overriding `Error.prepareStackTrace` is ignored when the `--enable-source-maps` flag is set. +### `--experimental-abortcontroller` + + +Enable experimental `AbortController` and `AbortSignal` support. + ### `--experimental-import-meta-resolve` + +> Stability: 1 - Experimental + + + +A utility class used to signal cancelation in selected `Promise`-based APIs. +The API is based on the Web API [`AbortController`][]. + +To use, launch Node.js using the `--experimental-abortcontroller` flag. + +```js +const ac = new AbortController(); + +ac.signal.addEventListener('abort', () => console.log('Aborted!'), + { once: true }); + +ac.abort(); + +console.log(ac.signal.aborted); // Prints True +``` + +### `abortController.abort()` + + +Triggers the abort signal, causing the `abortController.signal` to emit +the `'abort'` event. + +### `abortController.signal` + + +* Type: {AbortSignal} + +### Class: `AbortSignal extends EventTarget` + + +The `AbortSignal` is used to notify observers when the +`abortController.abort()` method is called. + +#### Event: `'abort'` + + +The `'abort'` event is emitted when the `abortController.abort()` method +is called. The callback is invoked with a single object argument with a +single `type` propety set to `'abort'`: + +```js +const ac = new AbortController(); + +// Use either the onabort property... +ac.signal.onabort = () => console.log('aborted!'); + +// Or the EventTarget API... +ac.signal.addEventListener('abort', (event) => { + console.log(event.type); // Prints 'abort' +}, { once: true }); + +ac.abort(); +``` + +The `AbortController` with which the `AbortSignal` is associated will only +ever trigger the `'abort'` event once. Any event listeners attached to the +`AbortSignal` *should* use the `{ once: true }` option (or, if using the +`EventEmitter` APIs to attach a listener, use the `once()` method) to ensure +that the event listener is removed as soon as the `'abort'` event is handled. +Failure to do so may result in memory leaks. + +#### `abortSignal.aborted` + + +* Type: {boolean} True after the `AbortController` has been aborted. + +#### `abortSignal.onabort` + + +* Type: {Function} + +An optional callback function that may be set by user code to be notified +when the `abortController.abort()` function has been called. + ## Class: `Buffer`