以下代码块在 Node 和浏览器之间执行不同。当然,存在不同的环境、不同的处理时间和竞争条件的可能性。但根据我对 Promises 的理解,这段代码在环境之间应该是一致的。
我期待 Chrome/浏览器的结果。我不期望 NodeJs 结果。我不明白为什么每个 newPromise
的 then
链在 masterPromise
的 之前都没有完成 然后
链继续。换句话说,因为在 then fn
中将新的 Promise 返回到 masterPromise
promise-chain,我希望新 Promise 的 then-chain 在 masterPromise 之前完成 promise 链恢复。
如果有人能在下面的实现中找出一个漏洞,并解释为什么 NodeJs 结果有效,我会很高兴!
使用 chrome 44 和 Node 12.6。
例如:
'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);
});
});
Node :
registered 1
registered 2
registered 3
registered 1 (verbatim, syncronous echo)
registered 2 (verbatim, syncronous echo)
registered 3 (verbatim, syncronous echo)
Chrome :
registered 1
registered 1 (verbatim, syncronous echo)
registered 2
registered 2 (verbatim, syncronous echo)
registered 3
registered 3 (verbatim, syncronous echo)
最佳答案
I do not understand why each
newPromise
'sthen
chain is not completed before themasterPromise
'sthen
chain continues. A new Promise is returned to themasterPromise
promise-chain in a thenfn
, so shouldn't it wait for that before the masterPromise promise-chain resumes?
没有。看来你的误解是关于那个“masterPromise链”:没有这样的东西。
您有一个 masterPromise
,然后您从中链接了三个不同的 then
调用。当 masterPromise
解析时(即刻),它会看到 3 个回调并按注册顺序调用所有回调。它不关心这些回调做什么,它们是否异步,也不等待它们的 promise 结果。在你的例子中,它们都创建了 promise ,并通过它们推进了它们的子链,但这 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()
[…]
在这里我们可以看到发生了 3 个(独立的)resolve()
调用。他们将各自安排各自的回调(result
)尽快。这是 Node 和 Chrome 之间的区别:前者确实在同一时间执行超时回调(它们被安排在同一时间并具有相同的超时),而 Chrome 使用单独的时间。所以在 node 中,“asap”在三个回调之后,而在 Chrome 中,它在它们之间。两种实现都很好。
关于javascript - Promise 输出因 NodeJs 和浏览器而异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31756375/