Open domenic opened 8 years ago
I read the document - very interesting!
I must admit that the idea of adding a catch cancel
clause makes me a little nervous, though. As a thought experiment: it seems like a cancel completion is like a throw, except that it's not catchable by our unconditional catch clause (which is all that we have right now). Now, what if we had:
catch (x : SomeErrorType) {}
(suspend disbelief on the syntax and semantics for now).@@catchExplicit
.The semantics of the unconditional catch clause could then be modified so that it only catches exceptions if error[@@catchExplicit]
is falsey. We could set CancelError.prototype[@@catchExplicit]
to true, so that the only way to catch it would be to add an explicit handler for it.
try {
throw new CancelError("humbug");
} catch (x) {
// Not caught here
}
try {
throw new CancelError("humbug");
} catch (x : CancelError) {
// But it is caught here
}
This doesn't have the properties that you're looking for for promises, though, since the rejection handler would still (presumably) be called in such a situation. Also, a catch-all that doesn't catch something is really surprising!
Yeah. I agree it's a bit unsettling to invent a new parallel thing that shares so many of the semantics with throw completions. That is probably why typed catch is attractive. But I think there are a number of reasons why an approach like you suggest is suboptimal:
I really think that although they share similar mechanisms in terms of how they bubble, cancelations and exceptions are distinct. We shouldn't let their implementation-sameness cause us to conflate the two concepts.
I think the third state document is important, I'm writing a lot of cancellation aware code in C# and cancellation-as-exceptions is quite the annoyance for me.
I agree with Domenic on "third state" thinking, and this particular point seemed (perhaps surprisingly?) uncontroversial at TC39.
@domenic cancelIfRequested shouldn't accept a reason parameter. The reason should be given when requesting the cancellation. cancelIfRequested is just a "break point" for where cancellation can occur.
const token = new CancelToken(
(cancel) => {
setTimeout( () => { cancel("Timeout"); }, 5000 );
}
);
task(token);
@Kulvar this is a 2016 issue, cancel tokens are dead, third state is dead, we might revive them for Node (and the web platform has AbortController). Sorry.
I wrote up why I think cancelation should be a third state: https://github.com/domenic/cancelable-promise/blob/master/Third%20State.md
I wanted to use this issue to document the tweaks to your cancelation tokens I'd envision to be compatible with that. They are small:
CancelError
toCancelReason
; part of the whole third-state philosophy is that cancelations are not errors. This also avoids the awkwardness ofct.promise
fulfilling with an error, which is weird.throwIfRequested
tocancelIfRequested
, and have it synchronously do athrow cancel
instead of a plainthrow
. Also, maybe it should accept an argument for the cancelation reason?I think that's it. I'm not saying you should necessarily change the document (unless you definitely agree with me on third state, and want to tie the proposals together) but wanted to open the issue to make sure it was discussed.