Questions on cancellation

63 views
Skip to first unread message

Jake Archibald

unread,
May 11, 2015, 12:13:03 PM5/11/15
to blueb...@googlegroups.com
I'm really excited by the work done on cancellation here. This is a huge issue for the Fetch spec, as the fetch API has no way to cancel at the moment.

We were throwing ideas around at https://gist.github.com/jakearchibald/9a24f3c06f06b9c06a1e, and it's reassuring to see Bluebird's implementation is so close to where we were headed.

A couple of questions:

How do you handle promises resolved with promises, is it compatible with https://gist.github.com/jakearchibald/9a24f3c06f06b9c06a1e#handling-promises-resolved-with-promises ?

Do you have a smart solution to the gotcha mentioned in that section? As in, how to cancel a promise that has resolved with another promise that is yet to settle, and has a child-count greater than 1.

I'd love to see cancellable promises become standard, either has an addition to existing es6 promises, or as a subclass. Your work here is invaluable!

Petka Antonov

unread,
May 11, 2015, 1:23:05 PM5/11/15
to blueb...@googlegroups.com, jaffat...@gmail.com
Given:

    var outerFetchPromise = fetch(url);
    var resultPromise = outerFetchPromise.then(response => {
      var jsonPromise = response.json();
      var innerFetchPromise = jsonPromise.then(data => fetch(data.url));
      var textPromise = innerFetchPromise.then(r => r.text());
      return textPromise;
    });

If resultPromise.cancel() is called before the handler has executed, the handler will never execute

If resultPromise.cancel() is called after the handler has executed but before textPromise settles, it has the same effect as calling textPromise.cancel() + resultPromise will be cancelled. This seems to match what is written in the gist.

If resultPromise.cancel() is called after textPromise has settled, it will have no effect

> Do you have a smart solution to the gotcha mentioned in that section? As in, how to cancel a promise that has resolved with another promise that is yet to settle, and has a child-count greater than 1.

First I need to explain something. Resolving promise with a promise in bluebird doesn't retain reference from the target to the follower because it leads to memory leaks in many reasonable and intuitive patterns. Resolving promise with a promise is usually implemented like:

    target.then(followerResolve, followerReject)

(or some equivalent optimization, but the main point is all of them make target have a reference to follower). In bluebird follower instead becomes a proxy for the target (follower holds reference to target rather than other way around). This eliminates the memory leak but it makes it impossible to do branch counting for promises resolved with promises. So in bluebird the refcount would be 1 instead of 2 and you would need to use the `.then()` workaround to avoid cancelling for the other consumer.
Reply all
Reply to author
Forward
0 new messages