细则中指出 (第5):
从一个单一的作业队列中的PendingJob记录FIFO顺序总是启动。 该规范没有定义在多个作业队列被服务的顺序。 一个ECMAScript实现可交织的作业队列的PendingJob记录的FIFO评估与一个或多个其他作业队列的PendingJob记录的评价。
这是否意味着我不能提供给回调数.then
提供给回调之前被评估setTimeout
在另外的同步控制流程?
换句话说,我可以依靠以下打印one two
。
setTimeout(() => console.log('two')); Promise.resolve().then(() => console.log('one'));
这是否意味着我不能提供给回调数.then
提供给回调之前被评估setTimeout
在另外的同步控制流程?
是的,这就是它的意思; 该规范并不要求实现这样的。
但在实践中,与本地的实现Promise
支持我测试过它已计划在then
整理,定它为“宏任务”后,立即回调(从PendingJobs队列“microtask”),其他未决宏任务之前,即使在挂起宏任务是在microtask 前调度。 ( setTimeout
和事件是宏任务。)
例如,在我测试它的环境中,这种输出A
, C
, B
可靠:
console.log("A"); setTimeout(_ => console.log("B"), 0); Promise.resolve().then(_ => console.log("C"));
但JavaScript的规范并不需要它。
作为BERGI指出 ,对用户代理的环境中, HTML5规范涵盖这在其microtasks和宏任务规范。 但是,这仅适用于用户代理环境(如浏览器)。
节点不遵循规范的定义,例如(不仅是因为它的定时器函数返回的对象,而不是数字),但节点也给了我们A
, C
, B
之上,因为(感谢本杰明Gruenbaum!)它运行后承诺的决议nextTick
队列但任何定时器或I之前/ O回调。 见他依据的详细信息。
是的,这意味着什么 - 的其他事件可能承诺回调之前进行发射。
不,这不会发生-而ECMAScript的允许, setTimeout
规范没有。
setTimeout
并不意味着所提供的功能将所提供的时间后执行。 它添加了功能到队列的末尾,一旦延迟已经过去。
这真的取决于当你的承诺解决的,因为两个语句的执行。 在你的榜样, setTimeout
会增加它的回调来提前解决承诺的队列,所以你可以期待one two
。