Closed bergus closed 8 years ago
Right, that's the idea. I wasn't sure about this but the alternative seems worse, i.e. in your above example, despite having canceled the token which is tied to the function's lifetime, you get a fulfilled promise. What do you think?
Oh, I really like it, it just clashes a bit more with the "propagate cancellation downwards as a promise result" idea. We also need to consider the case
async function() {
const { token, cancel } = CancelToken.source();
await.cancelToken = token;
cancel();
try {
await moreWorkA(…);
} catch(e) {}
await.cancelToken = null; // or a new CancelToken()
await moreWorkB(…);
return result;
}
Here moreWorkA
is raced against an already cancelled token, which means it's disregared immediately, but moreWorkB
is not dealt with so favourably. It might be highly unexpected for users… but it's just an edge case.
Some ideas
throw
the Cancel on an await
when the token is already .requested
await.cancelToken
if the current token is already .requested
.requested
token to await.cancelToken
, make it throw the Cancel immediately (the current spec misses that case completly, not even rejecting the PromiseToReturn)You might want to read the source of my couroutine.cancel
implementation (like await.cancelToken
for generators) here and here for some inspiration or play around with it - while it does follow my own approach at cancellation in general, this stuff is very similar.
Very interesting. That edge-case is pretty troubling; in general the whole thing where we've already decided that the returned promise should be rejected, but we keep running code anyway, seems problematic, and your code highlights it.
I guess I see two approaches:
await.cancelToken
only impact await
s.
I'm probably missing something, but what is this necessary for and how is it supposed to work in the standard examples?
If I am not mistaken, the execution context's PromiseToCancel and PromiseToReturn are both set to
p
, making thecancel()
call reject the promise so that we are going to seeCancel(oops)
in the console, ignoring the return value. Is that expected?