是什么决定了使用 promises 或 setTimeout 的延迟函数的调用顺序?
What determines the call order of deferred function using promises or setTimeout?
延迟函数的执行,例如在自定义事件处理中,是 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 并且首先从块中出来。至少在节点中。
我在 Chrome 和 Firefox 中重复了测试,得到了相同的结果,但是在 Edge 中,结果显示为 3、1、2。我还希望非本地 promise 库在后台使用 setTimeout所以结果会和 Edge 一样。
是什么决定了这些调用的解析顺序?这些不同的环境使用什么模型来确定执行顺序?以上任何一项是否代表标准或非标准行为?
PS 我绝对不建议依赖任何这种保持一致性,我只是好奇。
在下面给出的答案为我指明了正确的方向之后,正如下面评论中简要提到的那样,我在一个很好的 article by Jake Archibald 中找到了完整的答案(示例与我上面的代码几乎相同)虽然我会在这里加起来而不是把它埋在评论中。
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);
}
一些解释可以在 priority between setTimeout and setImmediate
找到
来自 Microsoft 文档 - https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/performance/efficient-script-yielding/ and one more link - setImmediate method
延迟函数的执行,例如在自定义事件处理中,是 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 并且首先从块中出来。至少在节点中。
我在 Chrome 和 Firefox 中重复了测试,得到了相同的结果,但是在 Edge 中,结果显示为 3、1、2。我还希望非本地 promise 库在后台使用 setTimeout所以结果会和 Edge 一样。
是什么决定了这些调用的解析顺序?这些不同的环境使用什么模型来确定执行顺序?以上任何一项是否代表标准或非标准行为?
PS 我绝对不建议依赖任何这种保持一致性,我只是好奇。
在下面给出的答案为我指明了正确的方向之后,正如下面评论中简要提到的那样,我在一个很好的 article by Jake Archibald 中找到了完整的答案(示例与我上面的代码几乎相同)虽然我会在这里加起来而不是把它埋在评论中。
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);
}
一些解释可以在 priority between setTimeout and setImmediate
找到来自 Microsoft 文档 - https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/performance/efficient-script-yielding/ and one more link - setImmediate method