What should happen if you resolve a promise with another promise?

前端 未结 1 1143
忘掉有多难
忘掉有多难 2020-12-12 02:55

What does the ECMAScript 6.0 specification say about a Promise resolving another Promise? Should it adopt the state of the other Promise

1条回答
  •  囚心锁ツ
    2020-12-12 03:22

    What does the ECMAScript 6.0 specification say about a Promise resolving another Promise?

    You can read it yourself here: http://www.ecma-international.org/ecma-262/6.0/#sec-promise-resolve-functions
    When the argument is a thenable, a PromiseResolveThenableJob will be queued.

    Should it adopt the state of the other Promise by attaching a then to that Promise which would resolve this one?

    Yes. The .then() method will be called with a resolver and rejecter function.

    I tried this snippet in Chrome and here is what I get and it seems to just resolve the Promise1 with Promise2 is that fine?

    Yes. It's only resolved for now.


    I do have to admit, my current Chrome Version (48.0.2564.82, V8 4.8.271.17) doesn't exactly comply to this algorithm (which might not be a bad thing per se, and avoids memory problems, but can be unexpected).
    It is lazy, and only schedules the job once an actual callback is interested in the result. And it doesn't pass a resolver to the then method, but the actual callback that wants to know the result.

    > var resolve1, resolve2;
    > var promise1 = new Promise(function(r){ resolve1 = r; });
    > var promise2 = new Promise(function(r){ resolve2 = r; });
    > promise2.then = function(...args) { console.log(...args);
    >                                     return Promise.prototype.then.call(this, ...args); };
    > resolve1(promise2);
      undefined
    // you'd expected a call to the then method here
    > promise1
      Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Promise}
    > promise2
      Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
    > resolve2(42)
      undefined
    // or at least here
    > promise1
      Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Promise}
    > promise2
      Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 42}
    > promise1.then(x => console.log(x))
      x => console.log(x), PromiseIdRejectHandler() { [native code] }
      // but it only is here
      42
      Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
    > promise2.then(x => console.log(x))
      x => console.log(x)
      42
      Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
    > promise1.then(x => console.log(x))
      x => console.log(x), PromiseIdRejectHandler() { [native code] }
    // hell they're even calling it multiple times!
    42
    Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
    

    > var resolve1, resolve2;
    > var promise1 = new Promise(function(r){ resolve1 = r; });
    > var thenable = {then:function(r) { console.log(...arguments); resolve2 = r; }};
    > resolve1(thenable);
      undefined
    // you'd expected a call to the then method here
    > promise1
      Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Object}
    > thenable
      Object {}
    > resolve2(42)
      Uncaught TypeError: resolve2 is not a function(…)
    // uh. yeah.
    > promise1.then(x => console.log(x))
      () { [native code] }, () { [native code] }
    // ah there was the call, even with a resolver
      Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
    > resolve2(42)
      42
      undefined
    > promise1.then(x => console.log(x))
      () { [native code] }, () { [native code] }
    // but now they fucked up.
    // Instead of another call on the thenable, you'd expected the result to be logged
      Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
    > resolve2(42)
      42
    // OMG.
      undefined
    

    0 讨论(0)
提交回复
热议问题