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

Question about **promise resolution procedure** 2.3.2 #269

Open
nilptr opened this issue May 26, 2018 · 2 comments
Open

Question about **promise resolution procedure** 2.3.2 #269

nilptr opened this issue May 26, 2018 · 2 comments

Comments

@nilptr
Copy link

nilptr commented May 26, 2018

const p1 = new Promise((resolve, reject) => {
    const p2 = new Promise((resolve1) => {
        setTimeout(() => {
            resolve1(1);
        }, 1000);
    });

    resolve(p2);

    reject(2);
});

p1.then((value) => {
    console.log('fulfilled:', value);
}, (reason) => {
    console.log('rejected:', reason);
});

// my implementation which has pass all test cases of <https://github.com/promises-aplus/promises-tests>.
// reject: 2

// Node.js & Safari & Firefox & bluebird
// fulfilled: 1

The specification says:

2.1.1 When pending, a promise:
   2.1.1.1 may transition to either the fulfilled or rejected state.

2.3.2 If x is a promise, adopt its state [3.4]:
   2.3.2.1 If x is pending, promise must remain pending until x is fulfilled or rejected.
   2.3.2.2 If/when x is fulfilled, fulfill promise with the same value.
   2.3.2.3 If/when x is rejected, reject promise with the same reason.

According to my understanding of these, when resolve p1 with p2, p1 will remain pending until p2 is fulfilled 1 second later, so p1 can be rejected with 2 immediately. However in Node.js / browser / bluebird these implementations, p1 adopts the state of p2. Which behavior is correct ?

@ForbesLindesay
Copy link
Member

"adopt its state" means "permanently adopt its state" i.e. once you've adopted the state of p2, you ignore anything that would modify your own state, as you have already adopted the state of p2.

This is probably tied down more tightly in the ECMA Script specification, because that actually specifies how resolve and reject behave, but this spec only actually specifies what happens to values returned from .then callbacks.

@ForbesLindesay
Copy link
Member

A test case like:

Promise.resolve(null).then(() => ({
  then(resolve, reject) {
    const p2 = new Promise((resolve1) => {
      setTimeout(() => {
        resolve1(1);
      }, 1000);
    });

    resolve(p2);

    reject(2);
  }
})).then((value) => {
  console.log('fulfilled:', value);
}, (reason) => {
  console.log('rejected:', reason);
});

would actually be covered by the Promises/A+ specification. Your implementation must print "fulfilled: 1" to be Promises/A+

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

No branches or pull requests

2 participants