The spec says(第5段):
始终在单个作业队列中启动PendingJob记录 FIFO订单。该规范没有定义其中的顺序 多个作业队列得到服务。 ECMAScript实现可以 交织作业的PendingJob记录的FIFO评估 通过评估一个或多个PendingJob记录进行排队 其他工作队列。
这是否意味着在依赖于同步控制流的.then
回调之前,我无法依靠提供给setTimeout
的回调?
换句话说,我可以依赖以下打印one two
。
setTimeout(() => console.log('two'));
Promise.resolve().then(() => console.log('one'));

答案 0 :(得分:4)
这是否意味着在依赖于同步控制流的
.then
回调之前,我无法依靠提供给setTimeout
的回调?
是的,这意味着什么;规范没有要求这些实现以这种方式工作。
但实际上,我已经对其进行过测试的本地Promise
支持的实现已经安排了then
回调(来自PendingJobs队列的" microtask")完成" macrotask"在其他未决的macrotask之前安排它,即使在微任务之前调度挂起的macrotask时也是如此。 (setTimeout
和事件是macrotasks。)
,例如,在我对其进行测试的环境中,这会可靠地输出A
,C
,B
:
console.log("A");
setTimeout(_ => console.log("B"), 0);
Promise.resolve().then(_ => console.log("C"));

但JavaScript规范并不需要它。
作为Bergi points out,对于用户代理环境,其微型任务和宏任务规范中的HTML5 spec covers this。但这仅适用于用户代理环境(如浏览器)。
例如, Node并不遵循该规范的定义(尤其是因为它的计时器函数返回对象而不是数字),但Node也为我们提供了A
,{上面的{1}},C
,因为(感谢Benjamin Gruenbaum!)它在B
队列之后但在任何计时器或I / O回调之前运行承诺解析。有关详细信息,请参阅his gist。
答案 1 :(得分:2)
是的,这意味着什么 - 其他事件可能会在承诺回调之前触发。
不,这不会发生 - 虽然ECMAScript允许,但setTimeout
spec没有。
答案 2 :(得分:0)
setTimeout
并不意味着所提供的功能将在提供的时间之后执行。一旦延迟过去,它就会将函数添加到队列的末尾。
这实际上取决于你的承诺何时解决,以及两个陈述的执行。在您的示例中,setTimeout
会在已解决的承诺之前将其回调添加到队列中,因此您可以期待one two
。