微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript-Promise输出在NodeJ和浏览器之间有所不同

以下代码块在Node和browser之间的执行方式不同.当然,存在不同的环境,不同的处理时间和竞争条件的可能性.但是据我对Promises的理解,此代码在环境之间应保持一致.

我希望得到Chrome /浏览器的结果.我不期望NodeJ的结果.我不明白为什么在masterPromise的then链继续之前,每个newPromise的then链都没有完成.换句话说,由于新的Promise在随后的fn中返回到masterPromise承诺链,所以我希望新的Promise的then链在masterPromise承诺链恢复之前完成.

如果有人可以在下面的实现中戳出一个洞,并解释为什么NodeJs结果有效,我将很高兴!

使用Chrome 44和节点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 @R_690_4045@ion--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);
    });
});

节点:

registered 1
registered 2
registered 3
registered 1 (verbatim, syncronous echo)
registered 2 (verbatim, syncronous echo)
registered 3 (verbatim, syncronous echo)

铬:

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‘s then chain is not
completed before the masterPromise‘s then chain continues. A new
Promise is returned to the masterPromise promise-chain in a then
fn, so shouldn’t it wait for that before the masterPromise
promise-chain resumes?

不会.您的误解似乎与“ masterPromise链”有关:没有这样的事情.
您有一个masterPromise,然后从中链接了三个不同的调用.当masterPromise解析(立即执行)时,它会看到3个回调并按照注册顺序调用所有这些回调.不管这些回调是异步的还是非异步的,它都不在乎,并且不等待它们的承诺结果.在您的情况下,它们都创建了诺言,并通过它们来推进其子链,但是那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()调用正在发生.他们将尽快安排各自的回调(结果).这是node和Chrome之间的区别:前者的确在同一刻度内执行了相同时间的超时回调(它们是在同一时间以相同的超时进行调度的),而Chrome使用了不同的刻度.因此,在节点中,“ asap”在三个回调之后,而在Chrome中则在它们之间.两种实现都很好.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐