[ES7+] Promise cancellation (was: Re: Promise-returning delay function)

# Ron Buckton (11 years ago)

The direction I've taken around Promise cancellation given the API surface of the ES6 Promise has been to use a different object to handle cancellation. This approach is similar to the Cooperative Cancelation model used in .NET. The API for this looks something like the following (using TypeScript declarations):

declare class CancellationTokenSource {
   constructor(...linkedTokens: CancellationToken[]);
   state: string;
   token: CancellationToken;
   cancel(reason?: any): void;
   cancelAfter(delay: number, reason?: any): void;
   close(): void;
}

declare class CancellationToken {
  constructor(source: CancellationTokenSource);
  static none: CancellationToken;
  state: string;
  reason: any;
  throwIfCanceled(): void;
  register(callback: (reason: any) => void): void;
  unregister(callback: (reason: any) => void): void;
}

There are several reasons I'm using this approach:

  • Separates the concerns of cancellation (CTS/CancellationToken) from asynchronous completion (Promise)
  • Distinguishes the relationship between the producer and consumer of cancellation and completion signals:
    • A function that performs an asynchronous operation produces the completion signal, while the caller receives the signal.
    • The caller produces the cancellation signal, while the function that performs the asynchronous operation receives the signal.
  • A Promise guarantees all continuations are asynchronous, and will be scheduled in a later turn. Cancellation signals must be completed synchronously, lest the signal is scheduled after the Promise resolves.
  • The producer of a cancellation signal maintains sole control over the ability to signal cancellation. Consumers can merely listen for the signal.
  • Cancellation signals only propagate up the chain to a Promise producer who intentionally listens for the signal.
  • Cancellation signals cannot be sent by downstream consumers of a Promise API that does not expose its cancellation source.

I've created a gist[1] with a rough reference implementation of CTS/CancellationToken, along with examples of many of the above points.

However, this is not truly "cooperative" cancellation, when compared to the approach .NET takes. True Cooperative Cancellation would involve Promise internals being aware of a CancellationToken, and having a cancellation signal affect the state of the Promise automatically in some meaningful way.

Ron

[1] gist.github.com/rbuckton/256c4e929f4a097e2c16

# Andrea Giammarchi (11 years ago)

I've seen this too late ... but thank you, looking forward to read more in here.

Best