规范说 https://www.ecma-international.org/ecma-262/7.0/index.html#sec-jobs-and-job-queues(第 5 段):
来自单个作业队列的 PendingJob 记录始终在
先进先出顺序。本规范没有定义顺序
服务多个作业队列。 ECMAScript 实现可以
交织作业的 PendingJob 记录的 FIFO 评估
具有一个或多个 PendingJob 记录评估的队列
其他作业队列。
这是否意味着我不能指望提供给的回调.then
在回调提供给之前被评估setTimeout
在同步控制流中?
换句话说,我可以依赖下面的打印吗one two
.
setTimeout(() => console.log('two'));
Promise.resolve().then(() => console.log('one'));
这是否意味着我不能指望提供给的回调.then
在回调提供给之前被评估setTimeout
在同步控制流中?
是的,就是这个意思;规格没有require实现就是这样工作的。
但在实践中,使用原生的实现Promise
支持我已经测试过并已安排then
在完成调度它的“宏任务”之后立即回调(来自 PendingJobs 队列的“微任务”),在其他挂起的宏任务之前,即使挂起的宏任务已调度before微任务。 (setTimeout
事件是宏任务。)
例如,在我测试过的环境中,此输出A
, C
, B
可靠地:
console.log("A");
setTimeout(_ => console.log("B"), 0);
Promise.resolve().then(_ => console.log("C"));
但 JavaScript 规范并不要求它。
As 贝尔吉指出 https://stackoverflow.com/a/43592505/157247,对于用户代理环境,HTML5 规范涵盖了这一点 https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model在其微任务和宏任务的规范中。但这仅适用于用户代理环境(如浏览器)。
Node http://nodejs.org例如,不遵循该规范的定义(尤其是因为它的计时器函数返回对象,而不是数字),但 Node 还为我们提供了A
, C
, B
上面,因为(感谢本杰明·格伦鲍姆!)它在之后运行承诺决议nextTick
队列但在任何计时器或 I/O 回调之前。看his gist https://gist.github.com/benjamingr/9afb9c52facd31484d5fc2e382de44c7了解详情。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)