I agree that without synchronous inspection cancellation tokens become very
hard to deal with as you may be queued for a long time prior to
cancellation on the event loop, and then the operation is cancelled while
you are waiting to check for cancellation. Is there a reason to use a
Promise as the cancellation token, rather than have something that is
synchronously inspectable? Even a small class/interface like:

```javascript
let cancelled = false;
myPromise.then(() => cancelled = true);
task[Symbol.cancelled] = () => cancelled;
```

For this reason I do not think Promises are the right data type to handle
Cancellation. There are several existing uses of cancellation tokens that
are just `{[nameForIsCancelledMethod](): {/*return boolean here*/}}`.

There are several reasons I don't think Promises should be extended any
further, but that causes a divide amongst people wanting them to represent
all possible async tasks and me.


> I am also unsure when .whenCanceled is necessary (maybe for interfacing
> with cancelable systems that are not cancelation token aware, like XHR?).
> And it seems likely that the rejection path is not necessary.


I don't think so, but you do need to create a way to allow canceling the
task from inside of another task (can be done by having a data structure
that is passed in to your task runner). I had to do that while working with
Node's `.pipe` in
https://github.com/bmeck/managed-task/blob/master/lib/examples/lockfile.js#L66

I know VSCode has that event, maybe they can shed light on why?

On Mon, Jan 4, 2016 at 10:04 AM, Domenic Denicola <[email protected]> wrote:

> In general I agree that there is a nice conceptual symmetry, but IMO the
> day-to-day impedance mismatch would be simply too great. Compare:
>
> ```js
> async function f(cancelationToken) {
>   cancelationToken.then(() => console.log("FYI you have been canceled"));
>
>   await cheapOperation(cancelationToken);
>   if (cancelationToken.state === "fulfilled") {
>     throw new CanceledOperationError();
>   }
>   await expensiveOperation(cancelationToken);
> }
>
> const token = new Promise(resolve => {
>   cancelButton.onclick = resolve;
> });
>
> f(token);
> ```
>
> to the same thing with different names:
>
> ```js
> async function f(cancelationToken) {
>   cancelationToken.whenCanceled(() => console.log("FYI you have been
> canceled"));
>
>   await cheapOperation(cancelationToken);
>   if (cancelationToken.canceled) {
>     throw new CanceledOperationError();
>   }
>   await expensiveOperation(cancelationToken);
> }
>
> const token = new CancelationToken(cancel => {
>   cancelButton.onclick = cancel;
> });
>
> f(token);
> ```
>
> I am also unsure when .whenCanceled is necessary (maybe for interfacing
> with cancelable systems that are not cancelation token aware, like XHR?).
> And it seems likely that the rejection path is not necessary.
>
> So, if cancelation tokens are the right path, I'd prefer not reusing
> promises for them. Maybe it argues for easily being able to create a
> cancelation token from a promise, though.
>
> Semi-related: I was recently reading
> http://joeduffyblog.com/2015/11/19/asynchronous-everything/, which has a
> section on Cancelation.
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to