Download presentation
Presentation is loading. Please wait.
1
Cancellation Primitives
Ron Buckton - Microsoft Corporation
2
Clear and consistent approach to the cancellation of asynchronous operations
General purpose coordination primitive Host API integration (fetch, module loading, etc.) Motivations
3
Goals Separation of source and sink
Cancellation request can be observed synchronously, via property Cancellation request can be observed asynchronously, via callback Able to unregister callbacks Composable for non-trivial cancellation graphs Goals
4
Source/Sink Source Sink Owned by caller Received by callee
Can share entangled Sink with multiple callees Initiates cancellation signal Received by callee Can observe cancellation state Cannot initiate cancellation signal on Source Callee A cannot interfere with Callee B using the same Sink Source/Sink
5
Observability Synchronous Asynchronous
Observe cancellation request via property Useful for loops and multi-phase operations in async functions Game Loops Async Iteration Best for async functions Observe cancellation request via callback Able to unregister/unsubscribe from cancellation Allows GC of closures Stop listening when callback is no longer needed Best for non-async functions that return Promise Observability
6
ComposabLE Parent/Child Aggregation Root Child1 Child2 Child3
Aggregate Source1 Source2 Source3 ComposabLE
7
Current Proposals Promise as Token AbortController (WHATWG)
CancellationToken (TC39) Current Proposals
8
function asyncfn(token) { token. then(() => { /. cancelled
function asyncfn(token) { token.then(() => { /*cancelled*/ }); } let cancel, token = new Promise(resolve => cancel = resolve); asyncfn(token); cancel(); Promise as Token
9
Promise as Token Uses existing API Cannot be observed synchronously
Can be observed asynchronously Cannot be unregistered Must use additional logic to prevent execution Closure persists for lifetime of source Not easily composable Promise as Token
10
AbortController (WHATWG)
function asyncfn(signal) { const onabort = () => { /*cancelled*/ }; signal.addEventListener('abort', onabort); signal.removeEventListener('abort', onabort); if (signal.aborted) { /*cancelled */ } } const controller = new AbortController(); asyncfn(controller.signal); controller.abort(); AbortController (WHATWG)
11
AbortController (WHATWG)
New API: Can be observed synchronously Can be observed asynchronously Takes dependency on DOM events Callbacks can be removed (via removeEventListener) AbortController (WHATWG)
12
function asyncfn(token) { const reg = token. register(() => { /
function asyncfn(token) { const reg = token.register(() => { /*cancelled*/ }); reg.unregister(); if (token.cancellationRequested) { /*cancelled*/ } } const source = new CancellationTokenSource(); asyncfn(source.token); source.cancel(); CancellationToken
13
New API: https://github.com/tc39/proposal-cancellation
Can be observed synchronously Can be observed asynchronously Callbacks can be removed (via unregister) Easily composable: async function asyncfn(token1, token2) { const source = new CancellationTokenSource([token1, token2]); setTimeout(() => source.cancel(), 500); await otherfn(source.token); } CancellationToken
14
CancellationToken API
CancellationTokenSource new CancellationTokenSource([linkedTokens]) source.token source.cancel() source.close() CancellationToken API
15
CAncellationToken API
CancellationToken.none CancellationToken.canceled token.cancellationRequested token.canBeCanceled token.throwIfCancellationRequested() token.register(callback) registration.unregister() CAncellationToken API
16
Possible Future Interop
Promise new Promise(executor, token) promise.then(onfulfill, onreject, token) Observable observable.subscribe(observer, token) Dynamic import import(“module”, token) Possible Future Interop
17
Status Stage 0 Identified Champions: Ron Buckton, Brian Terlson
Strawman available Early Spec Proposal available Prototype available Requesting Stage 1 Status
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.