Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

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

What does the ECMAScript 6.0 specification say about a Promise resolving another Promise? Should it adopt the state of the other Promise by attaching a then to that Promise which would resolve this one?

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?

> Promise1 = new Promise(function(resolve){ResolveYouLater1 = resolve})
> Promise2 = new Promise(function(resolve){ResolveYouLater2 = resolve})
> ResolveYouLater1(Promise2)
  undefined
> Promise1
  Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Promise}

I thought it should attach a then to Promise2 which should ResolveYouLater1(value) when Promise2 is the settled.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...