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

推迟函数的执行,例如在自定义事件处理中,是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)(); 

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

我在Chrome和Firefox中重复了testing,结果相同,但是在Edge中出现了3,1,2。我也希望非本地的promise库能够在后台使用setTimeout,所以会和Edge一样。

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

附言我没有build议依靠任何这种保持一致,我只是好奇。


在下面给出的答案指出我正确的方向,正如在下面的评论中简要提到的,我在杰克·阿奇博尔德杰克·阿奇博尔德 ( 杰克·阿奇博尔德的一篇杰出的文章中find了完整的答案(与上面的代码几乎相同),我虽然我加在这里,而不是把它埋在评论里。

这取决于resolve()是如何在内部实现的 – 可能你会观察setTimeout(fn, 0)setImmediate(fn) 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); } 

比setTimeout和setImmediate之间的优先级更高

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