【发布时间】:2021-05-17 07:25:20
【问题描述】:
我对 JS 中异步任务如何调度的理解
如果我有任何错误,请纠正我:
JS 运行时引擎代理由事件循环驱动,该循环收集任何用户和其他事件,将任务排入队列以处理每个回调。
事件循环不断运行,有如下思考过程:
- execution context stack(通常称为调用堆栈)是否为空?
- 如果是,则将微任务队列(或作业队列)中的任何微任务插入调用堆栈。继续这样做,直到微任务队列为空。
- 如果微任务队列为空,则将任务队列(或回调队列)中最旧的任务插入调用堆栈
因此,任务和微任务的处理方式有两个关键区别:
- 微任务(例如 promises 使用微任务队列来运行其回调)优先于任务(例如来自其他 Web API 的回调,例如 setTimeout)
- 此外,所有微任务都在任何其他事件处理或呈现或任何其他任务发生之前完成。因此,微任务之间的应用环境基本相同。
Promise 在ES6 2015 中引入。我假设 ES6 中也引入了微任务队列。
我的问题
引入微任务队列的动机是什么?为什么不继续使用任务队列来处理 Promise?
更新 #1 - 我正在寻找对规范进行此更改的明确历史原因 - 即它旨在解决的问题是什么,而不是关于微任务队列的好处的固执己见的答案。
参考资料:
【问题讨论】:
-
我猜“微任务之间的应用程序环境基本相同”就可以了。通常,它允许链接同步事物 (
Promise.resolve(1).then(x => x+1).then(console.log)) 的承诺代码立即运行,而不会被处理事件等更大的任务中断。它也可以通过一个循环服务多个队列和明确的优先级规则来完成。 -
引入它的历史原因是使其成为 ECMAScript 规范的一部分,而事件循环是由嵌入器定义的功能(在 HTML 的情况下,由 WHATWG 指定)跨度>
-
@Bergi - 我建议你写一个答案。
标签: javascript asynchronous ecmascript-6 promise event-handling