Alternative way to achieve cancelable promise

Kagami Rosylight saschanaz at outlook.com
Sat Oct 15 07:15:26 UTC 2016


I want to find a way to replace cancellation token in the current [stage 1 cancelable promise proposal](https://github.com/tc39/proposal-cancelable-promises) with an alternative way which does not require passing an additional parameter.

Here is a short representation of [my current thought](https://github.com/SaschaNaz/cancelable):

```ts
// A cancelable object supports new `Symbol.cancel`.
// `object[Symbol.cancel]()` will cancel any tasks related to the object.
interface Cancelable {
  [@@cancel](): void;
}

interface Promise extends Cancelable {}
```

```js
// Here, a new `chain` object from promise constructor callback will
// help chaining cancelable tasks and provide cancellation related
// helper functions.

function foo() {
  return new Promise(async (resolve, reject, chain) => {
    await nonCancelableSubWork1();
    chain.throwIfCanceled(); // This line will throw `Cancel` object if the promise got a cancellation request
    await nonCancelableSubWork2();
    resolve();
 });
}

function bar() {
  return new Promise(async (resolve, reject, chain) => {
     // This `chain()` call will register foo() to the cancellation chain of a promise instance
     // and will propagate cancellation to the chained tasks.
     // The chain can receive any object that supports `Symbol.cancel`.
     await chain(foo());
     await chain(baz());
 });
}

const promise =  bar();
promise.cancel(); // This will cancel `bar` call and the cancellation will propagate to `foo` and `baz`
```

And with some syntax sugar for readability:

```js
cancelable function foo() {
  // `chain` is a keyword inside cancelable function blocks
  await nonCancelableSubWork1();
  chain.throwIfCanceled(); // similar form like `new.target`
  await nonCancelableSubWork2();
}

cancelable function bar() {
  chain foo();
  chain baz();
}

const promise = bar();
promise.cancel();

cancelable function baz() {
  try {
    chain baw();
  }
  else {
    // try-else block will catch cancellation, as the current existing proposal does
  }
}
```

I think this will achieve easier and more readable flow of cancelable tasks, what do you think?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20161015/691c7b8c/attachment-0001.html>


More information about the es-discuss mailing list