Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unwrapping resolved promises don't happen asynchronously #965

Closed
msiconolfi opened this issue Jan 19, 2016 · 6 comments
Closed

Unwrapping resolved promises don't happen asynchronously #965

msiconolfi opened this issue Jan 19, 2016 · 6 comments
Labels

Comments

@msiconolfi
Copy link

Sorry if this a more appropriate question for StackOverflow, thought I would ask here first.

Not sure if this was mentioned before, but I was reading @getify You Don't Know JS - Async & Performance and came across the following example which seems to behave differently using bluebird than using the author's native-promise-only promise library.

The following code snippet is a node.js program that has previously installed the following:
npm install --save-dev native-promise-only bluebird

// file: p03-scheduling-quirks.js
var promiseImpls = [
    'bluebird',
    'native-promise-only'
];

promiseImpls.forEach(function(promiseImpl) {

    var Promise = require(promiseImpl);
    var p3 = new Promise( function(resolve, reject){
        resolve( 'B');
    } );

    var p1 = new Promise( function(resolve, reject){
        resolve( p3 );
    } );

    var p2 = new Promise( function(resolve, reject){
        resolve( 'A' );
    } );

    p1.then( function(v) {
        console.log('Using ' + promiseImpl);
        console.log( v );
    } );

    p2.then( function(v) {
        console.log('Using ' + promiseImpl);
        console.log( v );
    } );
});

Output after running:

± node p03-scheduling-quirks.js
Using native-promise-only
A
Using native-promise-only
B
Using bluebird
B
Using bluebird
A

@getify states that according to spec (still looking for the source):

The specified behavior is to unwrap p3 into p1, but asynchronously, so p1's callback(s) are behind p2's callback(s) in the asynchronous Job queue.

I've also ran the code snippet in a ES6 fiddle to see what happens and get the same behavior as using native-promise-only.

Question
I understand that this is quirky behavior and in general one should not assume anything about the order of callbacks, but can anyone comment on why bluebird promises behave this way? Is it for performance?

@benjamingr
Copy link
Collaborator

Someone pinged getify here again, everyone run.

(Joke is a reference to an older discussion we've had about unrelated stuff - in practice we're actually all cool - I think I'm even mentioned in that chapter IIRC).

@benjamingr
Copy link
Collaborator

The spec does not mandate the order here. You can check different platforms with native promises (like other JS engines) and get varying results.

NPO and bluebird probably just use different schedulers and both results are valid.

Resolution is always synchronous (promise constructor has to run synchronously) - what's "asynchronous" is the onFulfilled callbacks executing.

@benjamingr
Copy link
Collaborator

I'm starting to wonder if this is correct - as EnqueueJob is called on resolution itself in the spec.

@benjamingr
Copy link
Collaborator

So Promise.resolve(x) calls NewPromiseCapability which does GetCapabilitiesExecutor which assumes resolve/reject arguments.but those are not passed to it.

I'm missing something. @domenic care to tell me what I'm missing in the spec?

@petkaantonov
Copy link
Owner

They are called asynchronously, just in different order. It was impossible to have same order as native promises without suffering from the memory leak native promsies suffer from (promises-aplus/promises-spec#183, promises-aplus/promises-spec#179).

@msiconolfi
Copy link
Author

Thanks for clarifying @petkaantonov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants