tc39 / proposal-cancelable-promises

Former home of the now-withdrawn cancelable promises proposal for JavaScript
Other
376 stars 29 forks source link

Adopt the sate of promises without taking a reference #1

Closed ForbesLindesay closed 8 years ago

ForbesLindesay commented 9 years ago

See promises-aplus/promises-spec#179

The basic idea is to implement a new state "adopted", which reverses the references. Incidentally, it's still possible to get a memory leak with something like:

function run() {
    return  new Promise(function(resolve) {
        setImmediate(resolve);
    }).then(run);
}

// here this `x` will keep a reference to the entire gradually expanding chain of promises
var x = run();

but this fixes the leak in the case of:

function run() {
    return  new Promise(function(resolve) {
        setImmediate(resolve);
    }).then(run);
}
run().then(function () {
  console.log('this never actually gets called');
});

I'm not sure if it's possible to fix both scenarios.

ForbesLindesay commented 9 years ago

I've commented in promises-aplus/promises-spec#179, I think it would require weak-references to fix both cases simultaneously. Can we have weak references in this repo?

domenic commented 9 years ago

This will change observable ordering, right? Can you add a test that shows how (i.e. fails beforehand and passes after)?

Regarding weak references, that's a harder sell. Would weak maps suffice? (Or, better yet, setting internal slots on promise objects besides yourself.)

domenic commented 9 years ago

Hmm this does not work with promise subclasses since it no longer calls the (possibly-overriden) .then method. But I am not sure what a solution could be given that constraint.

domenic commented 9 years ago

Maybe instead of directly transferring the [[FulfillReactions]] and [[RejectReactions]] (both in AdoptPromise and in PerformPromiseThen) we can just call adoptee.then(...) appropriately. Will have to try it.