CancellableHandle
CancellableHandle is the object returned by cancellable and all APIs built on top of it. It represents the external interface to a cancellable operation — the caller uses it to await, cancel, and inspect the task.
For executor APIs, exec() returns TaskHandle<T>, which extends CancellableHandle<T> with the same await/cancel behavior.
External interface
CancellableHandleis what the caller holds. The task itself receives aCancellableToken.
Import
Section titled “Import”Root package:
import { CancellableHandle } from "@vgerbot/async";Module subpath:
import { CancellableHandle } from "@vgerbot/async/cancellable";Leaf subpath:
import { CancellableHandle } from "@vgerbot/async/cancellable/CancellableHandle";Quick example
Section titled “Quick example”import { cancellable } from "@vgerbot/async";
const handle = cancellable(async (token) => { await token.sleep(5000); return "done";});
// Await the resultconst result = await handle;
// Or cancel ithandle.cancel("No longer needed");
// Check stateconsole.log(handle.isCancelled());class CancellableHandle<T> extends Defer<T> { readonly promise: Promise<T>; readonly signal: AbortSignal; readonly name: string | undefined;
cancel(reason?: unknown): void; isCancelled(): boolean; get cancelError(): CancelError | null; get cancelReason(): CancelError | null;
then<TResult1 = T, TResult2 = never>( onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: unknown) => TResult2 | PromiseLike<TResult2>, ): Defer<TResult1 | TResult2>;
catch<TResult = never>( onrejected?: (reason: unknown) => TResult | PromiseLike<TResult>, ): Defer<T | TResult>;
finally(onfinally?: () => void): Defer<T>;}Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
promise |
Promise<T> |
The underlying promise. Inherited from Defer<T>. |
signal |
AbortSignal |
The AbortSignal associated with this handle. Can be passed to other APIs. |
name |
string | undefined |
Optional name assigned to the task (from CancellableOptions.name). |
cancelError |
CancelError | null |
The CancelError if the handle was cancelled, otherwise null. |
cancelReason |
CancelError | null |
Backward-compatible alias for cancelError. |
Methods
Section titled “Methods”cancel(reason?)
Section titled “cancel(reason?)”Cancels the task. The reason is passed to the CancelError and can be any value.
handle.cancel("User navigated away");handle.cancel(new Error("Timeout"));handle.cancel(); // No reasonisCancelled()
Section titled “isCancelled()”Returns true if the handle has been cancelled.
if (handle.isCancelled()) { console.log("Task was cancelled");}Promise-like interface
Section titled “Promise-like interface”CancellableHandle implements PromiseLike<T>, so you can use await directly on the handle or call .then(), .catch(), and .finally().
// Direct awaitconst result = await handle;
// .then()handle.then((value) => console.log(value));
// .catch()handle.catch((error) => console.error(error));
// .finally()handle.finally(() => console.log("done"));Prefer
await handleCancellableHandleextendsDefer<T>which implementsPromiseLike<T>, soawait handleis the recommended concise form. Usehandle.promiseonly when you need to pass the rawPromiseto code that doesn’t understandPromiseLike.
Cancellation
Section titled “Cancellation”Calling cancel() triggers the following:
- The
AbortSignalis aborted with the given reason. - The
CancellableTokeninside the task receives the cancellation signal. - The task’s
onCancelcallback (if provided in options) is called. - The promise rejects with a
CancelError(unless already settled).
const handle = cancellable( async (token) => { await token.sleep(10_000); return "done"; }, { onCancel: () => console.log("Cleanup"), },);
handle.cancel("User cancelled");
try { await handle;} catch (error) { if (error instanceof CancelError) { console.log(error.reason); // "User cancelled" }}Linking signals
Section titled “Linking signals”The signal property can be passed to other APIs that accept AbortSignal:
const handle = cancellable(async (token) => { const fetchHandle = cancellable( async (innerToken) => { return fetch("/api/data", { signal: innerToken.signal }); }, { signal: token.signal }, ); return fetchHandle;});
// Cancelling the outer handle cancels the inner one toohandle.cancel();TypeScript tips
Section titled “TypeScript tips”CancellableHandle is generic over T. The promise property is Promise<T>.
const handle: CancellableHandle<string> = cancellable(async () => "hello");
const value: string = await handle;Related APIs
Section titled “Related APIs”cancellable— creates aCancellableHandle.CancellableToken— the token passed to the task.CancelError— the error type on cancellation.