Что спецификация ECMAScript 6.0 говорит о Promise
решении другого Promise
? Должен ли он принять состояние другого Promise
, присоединив then
к этому Promise
, который разрешил бы это?
Я пробовал этот фрагмент в Chrome, и вот что я получаю, и кажется, что он просто разрешает Promise1
с Promise2
, это прекрасно?
> 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
является установленным.
Что спецификация ECMAScript 6.0 говорит о обещании, разрешающем другое обещание?
Вы можете прочитать его здесь: http://www.ecma-international.org/ecma-262/6.0/#sec-promise-resolve-functions
Когда аргумент является thenable, PromiseResolveThenableJob будет поставлен в очередь.
Должен ли он принять состояние другого обещания, присоединив тогда к этому обещанию, который разрешил бы это?
Да. Метод .then()
будет вызываться с помощью функции resolver и rejecter.
Я пробовал этот фрагмент в Chrome, и вот что я получаю, и кажется, что он просто разрешает Promise1 с Promise2, это прекрасно?
Да. Это только разрешено.
Я должен признать, что моя текущая версия 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