是什么决定了使用promises或setTimeout的延迟函数的调用顺序?

时间:2016-04-20 08:15:50

标签: javascript node.js events settimeout es6-promise

延迟执行函数(例如在自定义事件处理中)是JavaScript中的常见模式(例如,参见here)。以前使用setTimeout(myFunc,0)是唯一的方法,但是对于承诺,现在有另一种选择:Promise.resolve().then(myFunc)

我曾经认为这些几乎可以做同样的事情,但是在处理包含自定义事件的库时,我认为我发现是否存在差异,所以我将以下块放入节点:

var logfn=function(v){return function(){console.log(v)}};

setTimeout(logfn(1),0);
Promise.resolve().then(logfn(2));
logfn(3)();

我期待在控制台上看到3,1,2但是我看到了3,2,1。所以换句话说,Promise并不等同于使用setTimeout并且首先从块中出来。至少在Node中。

我在Chrome和Firefox中重复测试的结果相同,但是在Edge中它出现了3,1,2。我还希望非原生的promise库在引擎盖下使用setTimeout,所以会出现同样的问题作为边缘。

是什么决定了这些来电被解决的顺序?这些不同的环境使用什么模型来确定执行顺序?上述任何一种是否代表标准或非标准行为?

PS我真的没有暗示依赖任何一个这样的坚持,我只是好奇。

在下面给出的答案指出了正确的方向,并且正如下面评论中简要提到的那样,我在一个优秀的article by Jake Archibald中找到了完整的答案(示例与上面的代码几乎相同),我虽然我在这里加起来而不是将其隐藏在评论中。

1 个答案:

答案 0 :(得分:1)

ll取决于resolve()内部实施的方式 - 您可能会发现setTimeout(fn, 0)setImmediate(fn)的边缘实施之间存在差异

请考虑文章 - http://www.mattgreer.org/articles/promises-in-wicked-detail/以及实施resolve方法的方式。

function resolve(value) {
    // force callback to be called in the next
    // iteration of the event loop, giving
    // callback a chance to be set by then()
    setTimeout(function() {
        callback(value);
    }, 1);
}

可以在priority between setTimeout and setImmediate

找到一些表达方式

来自Microsoft文档 - https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/performance/efficient-script-yielding/以及另外一个链接 - setImmediate method