Skip to content
Buy me a coffee

Signals are real AbortSignals

EnhancedAbortController is an AbortController (it extends it), and controller.signal is the native AbortSignal that AbortController creates. Nothing wraps it.

const
const controller: EnhancedAbortController
controller
= new
new EnhancedAbortController(): EnhancedAbortController

An AbortController with .NET CancellationTokenSource features. It is an AbortController, and controller.signal is a real AbortSignal: pass it to fetch, AbortSignal.any, streams, timers and any other API that takes a signal.

@example

const controller = new EnhancedAbortController().abortAfter(TimeSpan.fromSeconds(5));
const response = await fetch(url, { signal: controller.signal });

EnhancedAbortController
();
const controller: EnhancedAbortController
controller
instanceof
var AbortController: {
new (): AbortController;
prototype: AbortController;
}

The AbortController interface represents a controller object that allows you to abort one or more Web requests as and when desired.

MDN Reference

AbortController
; // true
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
instanceof
var AbortSignal: {
new (): AbortSignal;
prototype: AbortSignal;
abort(reason?: any): AbortSignal;
any(signals: AbortSignal[]): AbortSignal;
timeout(milliseconds: number): AbortSignal;
}

The AbortSignal interface represents a signal object that allows you to communicate with an asynchronous operation (such as a fetch request) and abort it if required via an AbortController object.

MDN Reference

AbortSignal
; // true
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
===
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
; // true: always the same object
const
const combined: AbortSignal
combined
=
var AbortSignal: {
new (): AbortSignal;
prototype: AbortSignal;
abort(reason?: any): AbortSignal;
any(signals: AbortSignal[]): AbortSignal;
timeout(milliseconds: number): AbortSignal;
}

The AbortSignal interface represents a signal object that allows you to communicate with an asynchronous operation (such as a fetch request) and abort it if required via an AbortController object.

MDN Reference

AbortSignal
.
function any(signals: AbortSignal[]): AbortSignal

The AbortSignal.any() static method takes an iterable of abort signals and returns an AbortSignal.

MDN Reference

any
([
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
,
var AbortSignal: {
new (): AbortSignal;
prototype: AbortSignal;
abort(reason?: any): AbortSignal;
any(signals: AbortSignal[]): AbortSignal;
timeout(milliseconds: number): AbortSignal;
}

The AbortSignal interface represents a signal object that allows you to communicate with an asynchronous operation (such as a fetch request) and abort it if required via an AbortController object.

MDN Reference

AbortSignal
.
function timeout(milliseconds: number): AbortSignal

The AbortSignal.timeout() static method returns an AbortSignal that will automatically abort after a specified time.

MDN Reference

timeout
(5000)]);
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
.
AbortSignal.addEventListener<"abort">(type: "abort", listener: (this: AbortSignal, ev: Event) => any, options?: boolean | AddEventListenerOptions): void (+1 overload)

The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.

MDN Reference

addEventListener
('abort', () =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@see ― source

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@since ― v0.1.100

log
('aborted'));
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
.
AbortSignal.throwIfAborted(): void

The throwIfAborted() method throws the signal's abort AbortSignal.reason if the signal has been aborted; otherwise it does nothing.

MDN Reference

throwIfAborted
(); // native: throws signal.reason once aborted

So it works everywhere a signal does: fetch, fs/promises, timers/promises, stream.pipeline, events.once, child_process, AbortSignal.any, database and HTTP clients.

The controller adds three properties to its own signal. Their type is EnhancedSignal, which extends AbortSignal:

Member What it does
signal.register(cb) Same as register(signal, cb): runs cb(reason) on abort, returns a disposable AbortRegistration.
signal.whenAborted Same as whenAborted(signal): a promise of the reason. Cached, so reading it twice gives the same promise and adds one listener.
signal.canBeAborted Always true for a controller’s signal.
const
const controller: EnhancedAbortController
controller
= new
new EnhancedAbortController(): EnhancedAbortController

An AbortController with .NET CancellationTokenSource features. It is an AbortController, and controller.signal is a real AbortSignal: pass it to fetch, AbortSignal.any, streams, timers and any other API that takes a signal.

@example

const controller = new EnhancedAbortController().abortAfter(TimeSpan.fromSeconds(5));
const response = await fetch(url, { signal: controller.signal });

EnhancedAbortController
();
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
.
EnhancedSignal.register(callback: (reason: unknown) => void): AbortRegistration

Same as register(signal, callback).

register
((
reason: unknown
reason
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@see ― source

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@since ― v0.1.100

log
('cleanup',
reason: unknown
reason
));
const controller: EnhancedAbortController
controller
.
AbortController.abort(reason?: any): void

The abort() method of the AbortController interface aborts an asynchronous operation before it has completed.

MDN Reference

abort
('stop');
const
const reason: unknown
reason
= await
const controller: EnhancedAbortController
controller
.
EnhancedAbortController.signal: EnhancedSignal

The controller's signal: a real AbortSignal, always the same object.

signal
.
EnhancedSignal.whenAborted: Promise<unknown>

Same as whenAborted(signal): resolves with the reason once the signal aborts.

whenAborted
; // 'stop'

Signals you didn’t create (from fetch, a framework, AbortSignal.timeout) don’t have these properties. Use the standalone functions register and whenAborted, or the EnhancedAbortSignal helpers; they accept any AbortSignal.

Member Same as
controller.isAborted controller.signal.aborted
controller.reason controller.signal.reason
controller.isDisposed true after dispose()

EnhancedAbortSignal is a plain object of helpers, not a class. Every one returns or accepts real signals.

Helper What it gives you
EnhancedAbortSignal.none One shared signal that never aborts (.NET CancellationToken.None). Use it as a default for optional signals. Registering on it adds no listener.
EnhancedAbortSignal.aborted A new, already-aborted signal (a getter: a fresh one each read).
EnhancedAbortSignal.timeout(delay) AbortSignal.timeout that also accepts a TimeSpan. Infinity returns none; delays over 24.8 days use a chained timer.
EnhancedAbortSignal.any(signals) AbortSignal.any, skipping undefined, null and none. Returns none if nothing is left.
EnhancedAbortSignal.register, .whenAborted The standalone functions.
EnhancedAbortSignal.canBeAborted(signal) false only for none (.NET CanBeCanceled).
async function
function search(query: string, signal?: AbortSignal): Promise<Response>
search
(
query: string
query
: string,
signal: AbortSignal | undefined
signal
?:
interface AbortSignal

The AbortSignal interface represents a signal object that allows you to communicate with an asynchronous operation (such as a fetch request) and abort it if required via an AbortController object.

MDN Reference

AbortSignal
) {
// Optional caller signal plus our own 10 s budget; an undefined signal is skipped.
const
const combined: AbortSignal
combined
=
const EnhancedAbortSignal: {
none: AbortSignal;
readonly aborted: AbortSignal;
timeout(delay: Delay): AbortSignal;
any(signals: Iterable<AbortSignal | null | undefined>): AbortSignal;
register(signal: AbortSignal, callback: (reason: unknown) => void): AbortRegistration;
whenAborted(signal: AbortSignal): Promise<unknown>;
canBeAborted(signal: AbortSignal): boolean;
}

Helpers for any AbortSignal, including ones you didn't create (fetch, frameworks, AbortSignal.timeout). Every function returns or accepts real AbortSignals.

EnhancedAbortSignal
.
function any(signals: Iterable<AbortSignal | null | undefined>): AbortSignal

AbortSignal.any, skipping undefined/null (optional signals) and none. The native implementation releases its links when the result is garbage-collected, so per-request use on a long-lived signal doesn't leak.

any
([
signal: AbortSignal | undefined
signal
,
const EnhancedAbortSignal: {
none: AbortSignal;
readonly aborted: AbortSignal;
timeout(delay: Delay): AbortSignal;
any(signals: Iterable<AbortSignal | null | undefined>): AbortSignal;
register(signal: AbortSignal, callback: (reason: unknown) => void): AbortRegistration;
whenAborted(signal: AbortSignal): Promise<unknown>;
canBeAborted(signal: AbortSignal): boolean;
}

Helpers for any AbortSignal, including ones you didn't create (fetch, frameworks, AbortSignal.timeout). Every function returns or accepts real AbortSignals.

EnhancedAbortSignal
.
function timeout(delay: Delay): AbortSignal

AbortSignal.timeout that also accepts a TimeSpan, Infinity (returns none) and delays over 24.8 days. Aborts with a TimeoutError; never keeps the process alive.

timeout
(
class TimeSpan

An immutable time interval, stored in milliseconds. Modeled on .NET's TimeSpan.

@example

controller.abortAfter(TimeSpan.fromSeconds(30));
TimeSpan.fromMinutes(1).add(TimeSpan.fromSeconds(30)).totalSeconds; // 90

TimeSpan
.
TimeSpan.fromSeconds(seconds: number): TimeSpan
fromSeconds
(10))]);
return
function fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+1 overload)
fetch
(`/search?q=${
function encodeURIComponent(uriComponent: string | number | boolean): string

Encodes a text string as a valid component of a Uniform Resource Identifier (URI).

@param ― uriComponent A value representing an unencoded URI component.

encodeURIComponent
(
query: string
query
)}`, {
RequestInit.signal?: AbortSignal | null | undefined

An AbortSignal to set request's signal.

signal
:
const combined: AbortSignal
combined
});
}