| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8d4936d commit f30f931
12 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -282,6 +282,7 @@ module.exports = { | |||
| 282 | 282 | 'node-core/no-duplicate-requires': 'error', | |
| 283 | 283 | }, | |
| 284 | 284 | globals: { | |
| 285 | + AbortController: 'readable', | ||
| 285 | 286 | Atomics: 'readable', | |
| 286 | 287 | BigInt: 'readable', | |
| 287 | 288 | BigInt64Array: 'readable', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -197,6 +197,13 @@ Enable experimental Source Map v3 support for stack traces. | |||
| 197 | 197 | Currently, overriding `Error.prepareStackTrace` is ignored when the | |
| 198 | 198 | `--enable-source-maps` flag is set. | |
| 199 | 199 | ||
| 200 | + ### `--experimental-abortcontroller` | ||
| 201 | + <!-- YAML | ||
| 202 | + added: REPLACEME | ||
| 203 | + --> | ||
| 204 | + | ||
| 205 | + Enable experimental `AbortController` and `AbortSignal` support. | ||
| 206 | + | ||
| 200 | 207 | ### `--experimental-import-meta-resolve` | |
| 201 | 208 | <!-- YAML | |
| 202 | 209 | added: | |
@@ -1222,6 +1229,7 @@ Node.js options that are allowed are: | |||
| 1222 | 1229 | * `--disable-proto` | |
| 1223 | 1230 | * `--enable-fips` | |
| 1224 | 1231 | * `--enable-source-maps` | |
| 1232 | + * `--experimental-abortcontroller` | ||
| 1225 | 1233 | * `--experimental-import-meta-resolve` | |
| 1226 | 1234 | * `--experimental-json-modules` | |
| 1227 | 1235 | * `--experimental-loader` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,101 @@ The objects listed here are specific to Node.js. There are [built-in objects][] | |||
| 17 | 17 | that are part of the JavaScript language itself, which are also globally | |
| 18 | 18 | accessible. | |
| 19 | 19 | ||
| 20 | + ## Class: `AbortController` | ||
| 21 | + <!--YAML | ||
| 22 | + added: REPLACEME | ||
| 23 | + --> | ||
| 24 | + | ||
| 25 | + > Stability: 1 - Experimental | ||
| 26 | + | ||
| 27 | + <!-- type=global --> | ||
| 28 | + | ||
| 29 | + A utility class used to signal cancelation in selected `Promise`-based APIs. | ||
| 30 | + The API is based on the Web API [`AbortController`][]. | ||
| 31 | + | ||
| 32 | + To use, launch Node.js using the `--experimental-abortcontroller` flag. | ||
| 33 | + | ||
| 34 | + ```js | ||
| 35 | + const ac = new AbortController(); | ||
| 36 | + | ||
| 37 | + ac.signal.addEventListener('abort', () => console.log('Aborted!'), | ||
| 38 | + { once: true }); | ||
| 39 | + | ||
| 40 | + ac.abort(); | ||
| 41 | + | ||
| 42 | + console.log(ac.signal.aborted); // Prints True | ||
| 43 | + ``` | ||
| 44 | + | ||
| 45 | + ### `abortController.abort()` | ||
| 46 | + <!-- YAML | ||
| 47 | + added: REPLACEME | ||
| 48 | + --> | ||
| 49 | + | ||
| 50 | + Triggers the abort signal, causing the `abortController.signal` to emit | ||
| 51 | + the `'abort'` event. | ||
| 52 | + | ||
| 53 | + ### `abortController.signal` | ||
| 54 | + <!-- YAML | ||
| 55 | + added: REPLACEME | ||
| 56 | + --> | ||
| 57 | + | ||
| 58 | + * Type: {AbortSignal} | ||
| 59 | + | ||
| 60 | + ### Class: `AbortSignal extends EventTarget` | ||
| 61 | + <!-- YAML | ||
| 62 | + added: REPLACEME | ||
| 63 | + --> | ||
| 64 | + | ||
| 65 | + The `AbortSignal` is used to notify observers when the | ||
| 66 | + `abortController.abort()` method is called. | ||
| 67 | + | ||
| 68 | + #### Event: `'abort'` | ||
| 69 | + <!-- YAML | ||
| 70 | + added: REPLACEME | ||
| 71 | + --> | ||
| 72 | + | ||
| 73 | + The `'abort'` event is emitted when the `abortController.abort()` method | ||
| 74 | + is called. The callback is invoked with a single object argument with a | ||
| 75 | + single `type` propety set to `'abort'`: | ||
| 76 | + | ||
| 77 | + ```js | ||
| 78 | + const ac = new AbortController(); | ||
| 79 | + | ||
| 80 | + // Use either the onabort property... | ||
| 81 | + ac.signal.onabort = () => console.log('aborted!'); | ||
| 82 | + | ||
| 83 | + // Or the EventTarget API... | ||
| 84 | + ac.signal.addEventListener('abort', (event) => { | ||
| 85 | + console.log(event.type); // Prints 'abort' | ||
| 86 | + }, { once: true }); | ||
| 87 | + | ||
| 88 | + ac.abort(); | ||
| 89 | + ``` | ||
| 90 | + | ||
| 91 | + The `AbortController` with which the `AbortSignal` is associated will only | ||
| 92 | + ever trigger the `'abort'` event once. Any event listeners attached to the | ||
| 93 | + `AbortSignal` *should* use the `{ once: true }` option (or, if using the | ||
| 94 | + `EventEmitter` APIs to attach a listener, use the `once()` method) to ensure | ||
| 95 | + that the event listener is removed as soon as the `'abort'` event is handled. | ||
| 96 | + Failure to do so may result in memory leaks. | ||
| 97 | + | ||
| 98 | + #### `abortSignal.aborted` | ||
| 99 | + <!-- YAML | ||
| 100 | + added: REPLACEME | ||
| 101 | + --> | ||
| 102 | + | ||
| 103 | + * Type: {boolean} True after the `AbortController` has been aborted. | ||
| 104 | + | ||
| 105 | + #### `abortSignal.onabort` | ||
| 106 | + <!-- YAML | ||
| 107 | + added: REPLACEME | ||
| 108 | + --> | ||
| 109 | + | ||
| 110 | + * Type: {Function} | ||
| 111 | + | ||
| 112 | + An optional callback function that may be set by user code to be notified | ||
| 113 | + when the `abortController.abort()` function has been called. | ||
| 114 | + | ||
| 20 | 115 | ## Class: `Buffer` | |
| 21 | 116 | <!-- YAML | |
| 22 | 117 | added: v0.1.103 | |
@@ -226,6 +321,7 @@ The object that acts as the namespace for all W3C | |||
| 226 | 321 | [WebAssembly][webassembly-org] related functionality. See the | |
| 227 | 322 | [Mozilla Developer Network][webassembly-mdn] for usage and compatibility. | |
| 228 | 323 | ||
| 324 | + [`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController | ||
| 229 | 325 | [`TextDecoder`]: util.md#util_class_util_textdecoder | |
| 230 | 326 | [`TextEncoder`]: util.md#util_class_util_textencoder | |
| 231 | 327 | [`URLSearchParams`]: url.md#url_class_urlsearchparams | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -136,6 +136,9 @@ Enable FIPS-compliant crypto at startup. | |||
| 136 | 136 | Requires Node.js to be built with | |
| 137 | 137 | .Sy ./configure --openssl-fips . | |
| 138 | 138 | . | |
| 139 | + .It Fl -experimental-abortcontroller | ||
| 140 | + Enable experimental AbortController and AbortSignal support. | ||
| 141 | + . | ||
| 139 | 142 | .It Fl -enable-source-maps | |
| 140 | 143 | Enable experimental Source Map V3 support for stack traces. | |
| 141 | 144 | . | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,83 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Modeled very closely on the AbortController implementation | ||
| 4 | + // in https://github.com/mysticatea/abort-controller (MIT license) | ||
| 5 | + | ||
| 6 | + const { | ||
| 7 | + Object, | ||
| 8 | + Symbol, | ||
| 9 | + } = primordials; | ||
| 10 | + | ||
| 11 | + const { | ||
| 12 | + EventTarget, | ||
| 13 | + Event | ||
| 14 | + } = require('internal/event_target'); | ||
| 15 | + const { | ||
| 16 | + customInspectSymbol, | ||
| 17 | + emitExperimentalWarning | ||
| 18 | + } = require('internal/util'); | ||
| 19 | + const { inspect } = require('internal/util/inspect'); | ||
| 20 | + | ||
| 21 | + const kAborted = Symbol('kAborted'); | ||
| 22 | + | ||
| 23 | + function customInspect(self, obj, depth, options) { | ||
| 24 | + if (depth < 0) | ||
| 25 | + return self; | ||
| 26 | + | ||
| 27 | + const opts = Object.assign({}, options, { | ||
| 28 | + depth: options.depth === null ? null : options.depth - 1 | ||
| 29 | + }); | ||
| 30 | + | ||
| 31 | + return `${self.constructor.name} ${inspect(obj, opts)}`; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + class AbortSignal extends EventTarget { | ||
| 35 | + get aborted() { return !!this[kAborted]; } | ||
| 36 | + | ||
| 37 | + [customInspectSymbol](depth, options) { | ||
| 38 | + return customInspect(this, { | ||
| 39 | + aborted: this.aborted | ||
| 40 | + }, depth, options); | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + Object.defineProperties(AbortSignal.prototype, { | ||
| 45 | + aborted: { enumerable: true } | ||
| 46 | + }); | ||
| 47 | + | ||
| 48 | + function abortSignal(signal) { | ||
| 49 | + if (signal[kAborted]) return; | ||
| 50 | + signal[kAborted] = true; | ||
| 51 | + const event = new Event('abort'); | ||
| 52 | + if (typeof signal.onabort === 'function') { | ||
| 53 | + signal.onabort(event); | ||
| 54 | + } | ||
| 55 | + signal.dispatchEvent(event); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + class AbortController { | ||
| 59 | + #signal = new AbortSignal(); | ||
| 60 | + | ||
| 61 | + constructor() { | ||
| 62 | + emitExperimentalWarning('AbortController'); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + get signal() { return this.#signal; } | ||
| 66 | + abort() { abortSignal(this.#signal); } | ||
| 67 | + | ||
| 68 | + [customInspectSymbol](depth, options) { | ||
| 69 | + return customInspect(this, { | ||
| 70 | + signal: this.signal | ||
| 71 | + }, depth, options); | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + Object.defineProperties(AbortController.prototype, { | ||
| 76 | + signal: { enumerable: true }, | ||
| 77 | + abort: { enumerable: true } | ||
| 78 | + }); | ||
| 79 | + | ||
| 80 | + module.exports = { | ||
| 81 | + AbortController, | ||
| 82 | + AbortSignal, | ||
| 83 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | const { | |
| 4 | 4 | NumberParseInt, | |
| 5 | 5 | ObjectDefineProperty, | |
| 6 | + ObjectDefineProperties, | ||
| 6 | 7 | SafeMap, | |
| 7 | 8 | SafeWeakMap, | |
| 8 | 9 | StringPrototypeStartsWith, | |
@@ -58,6 +59,7 @@ function prepareMainThreadExecution(expandArgv1 = false) { | |||
| 58 | 59 | // (including preload modules). | |
| 59 | 60 | initializeClusterIPC(); | |
| 60 | 61 | ||
| 62 | + initializeAbortController(); | ||
| 61 | 63 | initializeDeprecations(); | |
| 62 | 64 | initializeWASI(); | |
| 63 | 65 | initializeCJSLoader(); | |
@@ -312,6 +314,30 @@ function initializeDeprecations() { | |||
| 312 | 314 | }); | |
| 313 | 315 | } | |
| 314 | 316 | ||
| 317 | + function initializeAbortController() { | ||
| 318 | + const abortController = getOptionValue('--experimental-abortcontroller'); | ||
| 319 | + if (abortController) { | ||
| 320 | + const { | ||
| 321 | + AbortController, | ||
| 322 | + AbortSignal | ||
| 323 | + } = require('internal/abort_controller'); | ||
| 324 | + ObjectDefineProperties(global, { | ||
| 325 | + AbortController: { | ||
| 326 | + writable: true, | ||
| 327 | + enumerable: false, | ||
| 328 | + configurable: true, | ||
| 329 | + value: AbortController | ||
| 330 | + }, | ||
| 331 | + AbortSignal: { | ||
| 332 | + writable: true, | ||
| 333 | + enumerable: false, | ||
| 334 | + configurable: true, | ||
| 335 | + value: AbortSignal | ||
| 336 | + } | ||
| 337 | + }); | ||
| 338 | + } | ||
| 339 | + } | ||
| 340 | + | ||
| 315 | 341 | function setupChildProcessIpcChannel() { | |
| 316 | 342 | if (process.env.NODE_CHANNEL_FD) { | |
| 317 | 343 | const assert = require('internal/assert'); | |
@@ -448,6 +474,7 @@ module.exports = { | |||
| 448 | 474 | setupWarningHandler, | |
| 449 | 475 | setupDebugEnv, | |
| 450 | 476 | prepareMainThreadExecution, | |
| 477 | + initializeAbortController, | ||
| 451 | 478 | initializeDeprecations, | |
| 452 | 479 | initializeESMLoader, | |
| 453 | 480 | initializeFrozenIntrinsics, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,6 +13,7 @@ const { | |||
| 13 | 13 | setupInspectorHooks, | |
| 14 | 14 | setupWarningHandler, | |
| 15 | 15 | setupDebugEnv, | |
| 16 | + initializeAbortController, | ||
| 16 | 17 | initializeDeprecations, | |
| 17 | 18 | initializeWASI, | |
| 18 | 19 | initializeCJSLoader, | |
@@ -112,6 +113,7 @@ port.on('message', (message) => { | |||
| 112 | 113 | if (manifestSrc) { | |
| 113 | 114 | require('internal/process/policy').setup(manifestSrc, manifestURL); | |
| 114 | 115 | } | |
| 116 | + initializeAbortController(); | ||
| 115 | 117 | initializeDeprecations(); | |
| 116 | 118 | initializeWASI(); | |
| 117 | 119 | initializeCJSLoader(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -95,6 +95,7 @@ | |||
| 95 | 95 | 'lib/wasi.js', | |
| 96 | 96 | 'lib/worker_threads.js', | |
| 97 | 97 | 'lib/zlib.js', | |
| 98 | + 'lib/internal/abort_controller.js', | ||
| 98 | 99 | 'lib/internal/assert.js', | |
| 99 | 100 | 'lib/internal/assert/assertion_error.js', | |
| 100 | 101 | 'lib/internal/assert/calltracker.js', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -281,6 +281,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | |||
| 281 | 281 | "experimental Source Map V3 support", | |
| 282 | 282 | &EnvironmentOptions::enable_source_maps, | |
| 283 | 283 | kAllowedInEnvironment); | |
| 284 | + AddOption("--experimental-abortcontroller", | ||
| 285 | + "experimental AbortController support", | ||
| 286 | + &EnvironmentOptions::experimental_abortcontroller, | ||
| 287 | + kAllowedInEnvironment); | ||
| 284 | 288 | AddOption("--experimental-json-modules", | |
| 285 | 289 | "experimental JSON interop support for the ES Module loader", | |
| 286 | 290 | &EnvironmentOptions::experimental_json_modules, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -102,6 +102,7 @@ class EnvironmentOptions : public Options { | |||
| 102 | 102 | bool abort_on_uncaught_exception = false; | |
| 103 | 103 | std::vector<std::string> conditions; | |
| 104 | 104 | bool enable_source_maps = false; | |
| 105 | + bool experimental_abortcontroller = false; | ||
| 105 | 106 | bool experimental_json_modules = false; | |
| 106 | 107 | bool experimental_modules = false; | |
| 107 | 108 | std::string experimental_specifier_resolution; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments