如果用另一个 promise 解决一个 promise 会发生什么?
What should happen if you resolve a promise with another promise?
ECMAScript 6.0 规范对 Promise
解析另一个 Promise
有何规定?它是否应该通过将 then
附加到可以解决此问题的 Promise
来采用另一个 Promise
的状态?
我在 Chrome 中尝试了这个片段,这是我得到的结果,它似乎只是用 Promise2
解决了 Promise1
这样可以吗?
> Promise1 = new Promise(function(resolve){ResolveYouLater1 = resolve})
> Promise2 = new Promise(function(resolve){ResolveYouLater2 = resolve})
> ResolveYouLater1(Promise2)
undefined
> Promise1
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Promise}
我认为它应该附加一个 then
到 Promise2,它应该 ResolveYouLater1(value)
当 Promise2
是固定的。
What does the ECMAScript 6.0 specification say about a Promise resolving another Promise?
你可以在这里自己阅读:http://www.ecma-international.org/ecma-262/6.0/#sec-promise-resolve-functions
当参数是 thenable 时,PromiseResolveThenableJob 将被排队。
Should it adopt the state of the other Promise by attaching a then to that Promise which would resolve this one?
是的。 .then()
方法将使用解析器和拒绝器函数调用。
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?
是的。目前只有 。
我不得不承认,我当前的 Chrome 版本(48.0.2564.82,V8 4.8.271.17)并不完全符合这个算法(这本身可能不是一件坏事,并且 ,但可能出乎意料)。
它是惰性的,只有在实际回调对结果感兴趣时才会安排作业。它不会将解析器传递给 then
方法,而是传递给想要知道结果的实际回调。
> 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
ECMAScript 6.0 规范对 Promise
解析另一个 Promise
有何规定?它是否应该通过将 then
附加到可以解决此问题的 Promise
来采用另一个 Promise
的状态?
我在 Chrome 中尝试了这个片段,这是我得到的结果,它似乎只是用 Promise2
解决了 Promise1
这样可以吗?
> Promise1 = new Promise(function(resolve){ResolveYouLater1 = resolve})
> Promise2 = new Promise(function(resolve){ResolveYouLater2 = resolve})
> ResolveYouLater1(Promise2)
undefined
> Promise1
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Promise}
我认为它应该附加一个 then
到 Promise2,它应该 ResolveYouLater1(value)
当 Promise2
是固定的。
What does the ECMAScript 6.0 specification say about a Promise resolving another Promise?
你可以在这里自己阅读:http://www.ecma-international.org/ecma-262/6.0/#sec-promise-resolve-functions
当参数是 thenable 时,PromiseResolveThenableJob 将被排队。
Should it adopt the state of the other Promise by attaching a then to that Promise which would resolve this one?
是的。 .then()
方法将使用解析器和拒绝器函数调用。
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?
是的。目前只有
我不得不承认,我当前的 Chrome 版本(48.0.2564.82,V8 4.8.271.17)并不完全符合这个算法(这本身可能不是一件坏事,并且
它是惰性的,只有在实际回调对结果感兴趣时才会安排作业。它不会将解析器传递给 then
方法,而是传递给想要知道结果的实际回调。
> 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