【发布时间】:2016-04-21 03:17:06
【问题描述】:
延迟函数的执行,例如在自定义事件处理中,是 JavaScript 中的一种常见模式(例如,参见 here)。过去,使用 setTimeout(myFunc,0) 是唯一的方法,但是有了 Promise,现在有了另一种选择: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,而是首先出现在块中。至少在节点中。
我在 Chrome 和 Firefox 中重复了测试,结果相同,但是在 Edge 中,结果为 3、1、2。我还希望非本地承诺库在后台使用 setTimeout,所以结果相同作为边缘。
是什么决定了这些调用的解决顺序?这些不同的环境使用什么模型来确定执行顺序?以上任何一项是否代表标准或非标准行为?
PS 我绝对不建议依赖任何这种保持一致,我只是好奇。
在下面给出的答案为我指明了正确的方向之后,正如下面评论中简要提到的那样,我在出色的 article by Jake Archibald 中找到了完整的答案(示例与我上面的代码几乎相同),我认为我会在这里加起来,而不是把它埋在评论中。
【问题讨论】:
-
FWIW,没有什么是保证异步执行的任何特定顺序。你不应该首先尝试依赖执行顺序。这使得这个问题成为关于实现细节的有趣讨论,但实际上没有实际意义。
-
也许吧,但我倾向于发现我的编码改进得越多,我就越了解它是如何联系在一起的,即使是间接的。在挖掘了下面的答案之后,我还几乎完全找到了我上面的示例以及完整的解释here。鉴于所有这些,我绝对可以看到特定情况下推送到微任务或宏任务队列可能是合适的,但请注意,当只有宏任务可用时,您需要确保没有任何东西被破坏
标签: javascript node.js events settimeout es6-promise