Cancelable promises proposal
Logan Smyth
loganfsmyth at gmail.com
Wed Aug 5 06:23:48 UTC 2015
Given your example of
```
let done = query.done;
done.then(updateView).then(log, logAbort);
done.ignore(updateView);
```
The core of my complaint comes down to control flow. To demonstrate, let's
convert this to a co generator so it's readable like sync code.
```
co(function*(){
try {
let result = yield query.done;
let update = yield updateView(result);
log(update);
} catch(err){
logAbort(err);
}
});
```
What you are asking for seems like a way to halt execution of the function,
without ever returning from the function, or executing either branch of the
try/catch. In synchronous code the only way to achieve this would be
`while(true){}`, which is terrible. There isn't really a world where I'd
expect that code to execute neither side, because promises are
fundamentally about chaining data together, not about listening for events.
Instead you might write your code like
```
let ignore = false;
let done = query.done;
done.then(result => ignore ? undefined : updateView(result).then(log,
logAbort));
ignore = true;
```
Your code is skipped, like you wanted, but the outer promise still resolves
eventually.
As for the duplicate handler question, imagine this:
```
let counter = 0;
function fn(){
return ++counter;
}
let original = Promise.resolve();
let result;
for (let i = 0; i < 10; i++){
result = original.then(fn);
}
result.then(output => console.log(output));
```
the result is `10` because `result` was the 10th promise and then the 10th
execution of `fn`. If the same promise were returned constantly, then this
would instead print `1`.
On Tue, Aug 4, 2015 at 9:06 PM, Glen Huang <curvedmark at gmail.com> wrote:
> Are there some example use-cases where being able to `.ignore` is
> preferable to having the promise reject?
>
>
> The purpose of .ignore() is to let promises show disinterest, by
> disinterest, i mean the situation that whatever happens to that promise, it
> shouldn't be observable to the callbacks. Making that promise pending
> forever is the correct way to do that IMO. Rejecting the promise means the
> callback is still interested in the rejecting case.
>
> I can't really see a case where you'd want to disconnect a promise handler
> without informing promises farther down the chain
>
>
> If you want to inform promises farther down the chain, you shouldn't
> disconnect the handler, you should let that aborted reason flow down the
> chain.
>
> Also to your question about adding multiple handlers, if that handler has
> side-effects, then it would definitely cause bugs if the same promise were
> returned for multiple calls to `.then` with the same callback.
>
>
> Are you talking about passing the same callback combination to .then()
> returns the same promise? Would you provide an example where it can cause
> bugs? I guessed it's dangerous, but not sure how it could fail. But let's
> say it causes bug, do you think .ignore() disconnecting all same callbacks
> in the current promise could cause bug too? Or it could behave
> counter-intuitively? I'm only using returning the same promise as a
> guidance on designing how ignore() works, .then() doesn't really have to
> behave that way.
>
> Finally, here is an example to demonstrate the use case.
>
> Given
>
> ```js
> let query = queryDB(sql);
> let updateView = data => render(data);
> let log = data => console.log(data);
> let logAbort = err => {
> if (err instanceof AbortError) console.error(reason);
> throw err;
> };
> ```
>
> Let's say you want to abort the query, but log the abortion in a child
> promise:
>
> ```js
> query.done.then(updateView).then(log, logAbort);
> query.abort();
> ```
>
> Or if you want to show disinterest that the query is irrelevant now:
>
> ```js
> let done = query.done;
> done.then(updateView).then(log, logAbort);
> done.ignore(updateView);
> ```
>
> Does this answer you question?
>
> On Aug 5, 2015, at 10:51 AM, Logan Smyth <loganfsmyth at gmail.com> wrote:
>
> Glen, sorry if this has been covered in other discussions, but it's not
> clear to me so I wanted to ask. Are there some example use-cases where
> being able to `.ignore` is preferable to having the promise reject? Promise
> chains are about defining flows of data and I can't really see a case where
> you'd want to disconnect a promise handler without informing promises
> farther down the chain, like your `.then(log)` in your example. To me
> anyway, the proposed `.ignore` seems like it adds boat-loads of complexity
> with unclear goals.
>
> Also to your question about adding multiple handlers, if that handler has
> side-effects, then it would definitely cause bugs if the same promise were
> returned for multiple calls to `.then` with the same callback.
>
>
> On Tue, Aug 4, 2015 at 5:32 PM, Glen Huang <curvedmark at gmail.com> wrote:
>
>>
>> On Aug 4, 2015, at 1:32 PM, Andrea Giammarchi <
>> andrea.giammarchi at gmail.com> wrote:
>>
>> only promises that has passed through their initialization the callback
>> would be cancelable,and this could be reflected through a `.cancelable`
>> property
>>
>>
>> That's precisely the problem. When you made a mistake and thought a
>> function should have the ability to abort, you wouldn't reflect
>> that `.cancelable` property, you would simply call abort(). Passing a
>> different object makes this less likely to happen since it's not thenable.
>>
>>
>> and pragmatists would never find out what should be the behavior once
>> aborted 'cause Promise can only reject and never be ignored.
>>
>>
>> What do you think of the ignore() method I proposed?
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150804/0b4557ad/attachment.html>
More information about the es-discuss
mailing list