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

Eua*_*ith 7 javascript events settimeout node.js es6-promise

推迟执行函数(例如在自定义事件处理中)是JavaScript中的常见模式(例如,请参见此处).曾经是使用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)();
Run Code Online (Sandbox Code Playgroud)

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

我在Chrome和Firefox中重复测试结果相同,但是在Edge中它出现了3,1,2.我还希望非原生的promise库在引擎盖下使用setTimeout,这样就会像Edge一样.

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

PS我坚决不建议依赖任何这种保持一致,我只是好奇.


在下面给出的答案指出了正确的方向,并且如下面的评论中简要提到的那样,我在Jake Archibald的一篇优秀文章中找到了完整的答案(示例几乎与我上面的代码完全相同),尽管我是加在这里而不是将其隐藏在评论中.

Krz*_*ski 2

ll 取决于resolve()内部实现方式 - 可能您会观察到setTimeout(fn, 0)和 Edge 实现之间的差异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);
}
Run Code Online (Sandbox Code Playgroud)

setTimeout 和 setImmediate 之间的优先级可以找到一些解释

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

  • 感谢您提供文章链接和对“setImmediate”的引用,这对我来说是新的。向上查找让我找到了polyfill [setImmediate](https://github.com/YuzuJS/setImmediate),这导致了之前关于[微任务和宏任务事件队列](http://stackoverflow.cs)之间差异的stackoverflow答案。 com/a/25933985/4098951)这似乎解释了发生了什么。我猜 Chrome 等人使用微任务事件队列来实现宏任务队列上的“setTimeout”承诺。也许,Edge 并没有做出这样的区分。 (2认同)