Ben*_*Ben 2 javascript promise
规范说(第 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 队列的“微任务”),在其他待处理的宏任务之前,即使当待处理的宏任务被安排在微任务之前。(setTimeout和事件是宏任务。)
例如,在我测试过它的环境中,这种输出A,C,B可靠:
console.log("A");
setTimeout(_ => console.log("B"), 0);
Promise.resolve().then(_ => console.log("C"));但是 JavaScript 规范不需要它。
正如Bergi 指出的那样,对于用户代理环境,HTML5 规范在其微任务和宏任务规范中涵盖了这一点。但这仅适用于用户代理环境(如浏览器)。
例如,Node不遵循该规范的定义(尤其是因为它的计时器函数返回对象,而不是数字),但是 Node 还给了我们A, C,B上面,因为(感谢 Benjamin Gruenbaum!)它在nextTick队列之后但之前运行承诺解析任何计时器或 I/O 回调。有关详细信息,请参阅他的要点。