Closed domenic closed 8 years ago
How does this related to the cancel callback?
new Promise((resolve, reject, cancel) => {
cancel();
return () => console.log(1);
});
new CancelablePromise((resolve, reject, cancel) => {
cancel();
return () => console.log(2);
});
cancel()
trigger the cancelation callback?cancel()
queue a microtask to trigger the cancelation callback?Promise
constructor accept a cancelation callback, or is it unique to CancelablePromise
?As of bdd175890e0099d61afe72ddba9a582741bd989f, regular promises are cancelable by the creator.
Here are my current answers for the above, but I'm not set on it:
Does cancel() trigger the cancelation callback?
No
Does cancel() queue a microtask to trigger the cancelation callback?
No
Does the Promise constructor accept a cancelation callback, or is it unique to CancelablePromise?
Unique to CancelablePromise
.
For what it's worth, having cancel as part of regular promises made everything a lot easier. Good call.
Sorry, in Tokyo this week, so time zones are a bit off... I agree with all your answers! Will check out the commit, but glad that this gave a nice simplification, as that's exactly what I was hoping for.
Not doing tasks.
The premise so far is that there are three states:
Each of these propagate downstream, so that
.then(undefined, undefined, undefined)
will produce a new promise in the exact same state (and with the same value/reason, if applicable).As such, I propose the following:
The canceled state is part of the base Promise
In particular, the constructor signature becomes
If the executor function uses the cancel() function to put the promise in the canceled state, then only onFinally handlers trigger.
Note that like resolve and reject, it is a no-op to call cancel if the promise is not in a pending state.
This allows the creation of promises which can only be canceled by their creator, but otherwise behave like you would expected a cancelable promise to behave. In particular, their canceled-ness propagates "downward" to any descendants.
Note: we could add a static
Promise.cancel()
to parallelPromise.resolve(v)
andPromise.reject(r)
, but that seems kind of pointless since canceled promises don't have any value or reason to make them interesting.The CancelablePromise subclass is a convenience for exposing cancelation to the consumer
The CancelablePromise subclass allows the addition of custom cancelation actions, besides just changing the state. And it adds a
.cancel()
method, which deals with refcounting, so that once the refcount reaches zero, it triggers the custom cancelation action and then changes the state.Furthermore, the
.then()
of CancelablePromises ensures that it increases the refcount, and returns a CancelablePromise whose cancelation action is to callparent.cancel()
. This is all as already planned.This ensures combinators work more correctly
Consider:
This should work. Right now,
Promise.all
does:c1
andc2
fulfilling; if both do, fulfillp
c1
orc2
rejecting; if either do, rejectp
.We then add:
c1
andc2
's finally handlers; once both occur, cancelp
(whichPromise.all
can do, since it createdp
).This doesn't solve all combinator problems; libraries using Promise.all instead of CancelablePromise.all have thrown away the ability to cancel the return value, after all.