以下代码块在Node和浏览器之间执行不同的操作。当然,存在不同的环境,不同的处理时间和竞争条件的可能性。但根据我对Promises的理解,这段代码应该在环境之间保持一致。
我希望Chrome /浏览器的结果。我不指望NodeJs的结果。我不明白为什么每个 我很乐意,如果有人可以在下面的实现中找到一个漏洞,并解释为什么NodeJs结果是有效的! 使用chrome 44和节点12.6。 例如: 节点: 铬:newPromise
的{{1}}链未在 then
的{{1}}链继续之前完成。换句话说,因为新的Promise被返回到当时masterPromise
中的then
promise链,我希望新的Promise的then-chain能够在masterPromise promise-chain恢复之前完成。 / p>
masterPromise
fn
'use strict';
var masterPromise = Promise.resolve();
var numbers = [ 1, 2, 3 ];
// function returns a new promise that fulfills in 100ms
// it logs two bits of information--one pre-resolve, & one post-resolve.
// because a `.then` is registered immediately, before the promised is
// fulfilled, i would expect the post-resolve console.log to be logged before
// any other logging
var returnNewPromise = function(number) {
var resolve;
var newPromise = new Promise(function(r) { resolve = r; });
newPromise.then(function() { console.log('registered ' + number + ' (verbatim, syncronous echo)'); });
setTimeout(function() {
console.log('registered ' + number);
resolve();
}, 100);
return newPromise;
};
numbers.forEach(function(number) {
var getChildPromise = function(number) {
return returnNewPromise(number);
};
return masterPromise.then(function() {
return getChildPromise(number);
});
});
答案 0 :(得分:2)
我不明白为什么每个newPromise then chain都不会立即执行其解析
然后 - 回调不会立即调用。
var resolve;
new Promise(function (r) { resolve = r; })
.then(function () { console.log(2); });
resolve();
console.log(1);
日志:
1
2
Promise resolving的行为类似于setTimeout
,没有延迟。
<强>更新强>
与setTimeout
的比较并不完全正确,因为有限制:
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Minimummaximum_delay_and_timeout_nesting
相似之处在于异步的承诺。
<强> UPDATE2:强>
-----------+------------
wait | resolved
-----------+------------
timeout1 | initial state
timeout2 |
-----------+------------
| timeout1 after 100 ms
timeout2 |
-----------+------------
| resolve1 then Chrome variant
| timeout2
-----------+------------
| timeout2 or Node variant
| resolve1
-----------+------------
两种变体均符合规范。 Chrome队列似乎在后续超时回调之前解决了回调问题。
答案 1 :(得分:2)
我不明白为什么每个
newPromise
的{{1}}链都没有 之前完成then
的{{1}}链继续。一个新的 承诺在当时返回到masterPromise
承诺链then
,所以不应该在masterPromise之前等待 承诺链简历?
没有。你的误解似乎是关于“masterPromise chain”:没有这样的事情
您有一个masterPromise
,然后您已经链接了三个不同的fn
来电。当masterPromise
结算(立即)时,它会看到3个回调,并按照注册顺序调用所有这些回调。 不关心这些回调是做什么的,无论它们是否是异步的,并且不等待它们的承诺结果。在你的情况下,所有这些都创造了承诺,并通过它们推进了他们的子链,但这3个子链完全相互独立。
使用更具描述性的日志记录来充实你的代码有助于理解你在做什么:
then
您将在此处看到的日志是
masterPromise
在这里,我们可以看到3个(独立的)function delay(number) {
console.log("creating promise for", number);
return new Promise(function(resolve) {
setTimeout(function() {
console.log('resolving promise with', number);
resolve(number);
}, 100);
});
};
function result(n) {
console.log("received", number);
}
var masterPromise = Promise.resolve();
masterPromise.then(function(){ delay(1).then(result); }); // chain 1
masterPromise.then(function(){ delay(2).then(result); }); // chain 2
masterPromise.then(function(){ delay(3).then(result); }); // chain 3
console.log("created chains");
来电。他们将尽快安排各自的回调(// .then chain 1 -------,
// .then chain 2 ------- \ -,
// .then chain 3 -------- \ -\ -,
created chains | | |
| | | 3 then callbacks in the order they were registered
creating promise for 1 <´ | |
// setTimeout 100 -----, | |
\ / |
creating promise for 2 | <-´ |
// setTimeout 100 ------ |-, /
| \ /
creating promise for 3 | | <-´
// setTimeout 100 ------ |- |-,
| | \
… | | | 3 timeout callbacks in the order they were scheduled
| | |
resolving promise with 1 <´ | |
// resolve() | |
[…] / |
resolving promise with 2 <-´ |
// resolve() /
[…] /
resolving promise with 3 <---´
// resolve()
[…]
) 。这里是节点和Chrome之间的区别:前者确实在同一时间点执行超时回调(它们是在相同的超时时间内同时安排),而Chrome使用单独的刻度。所以在节点中,“asap”是在三个回调之后,而在Chrome中它位于它们之间。两种实现都很好。