咱们在上一篇 《浅析 JS 中的EventLoop 事件循环》 中提到一个 Event Queue
,其实在事件循环中 queue 一共有两种,还有一种叫 Job Queue
html
其中git
Event Queue
在 HTML 规范中被称为Task Queue
,可是为了区分,通常都叫做Macrotask Queue
Job Queue
是在 ECMAScript 规范中谈及处理 Promise 回调时提到的,可是因为和 V8 中的实现比较类似,因此通常都称为Microtask Queue
Macrotasks 包含了解析 HTML、生成 DOM、执行主线程 JS 代码和其余事件如 页面加载、输入、网络事件、定时器事件等。从浏览器的角度,Macrotask 表明的是一些离散的独立的工做。github
常见应用setTimeout
, setInterval
, setImmediate
, requestAnimationFrame
, I/O
, UI rendering
web
Microtasks 则是为了完成一些更新应用程序状态的较小的任务,如处理 Promise 的回调和 DOM 的修改,以便让这些任务在浏览器从新渲染以前执行。Microtask 应该以异步的方式尽快执行,因此它们的开销比 Macrotask 要小,而且可使咱们在 UI 从新渲染以前执行,避免了没必要要的 UI 渲染。api
常见应用process.nextTick
, Promises
, Object.observe
, MutationObserver
promise
Event Loop 的实现须要至少一个 Macrotask Queue 和至少一个 Microtask Queue。为了便于理解,咱们都简化成一个。
简单来讲,Microtask Queue 具备更高的优先级,即执行一个 Macrotask 任务后,就会清空整个 Microtask Queue,此时若是有新的 Microtask 加入也会被执行。浏览器
因此咱们来看下面的代码:网络
执行顺序是什么?
咱们已经知道 setTimeout 是 Macrotask,Promise 是 Microtask,而这段代码从上到下执行也是一个 Macrotaskapp
步骤:webapp
script start
script end
,此时脚本执行完成(即完成了一个 Macrotask)promise1
,返回 undefinedpromise2
,该回调返回 undefinedsetTimeout
,Macrotask Queue 清空因此打印顺序为:
script start -> script end -> promise1 -> promise2 -> setTimeout
PS. 上面的这段代码执行流程,建议看原文的倒数第二篇参考文章,有动态交互操做能够演练。
整体的执行顺序为:常规代码
-> promises
-> events 和 setTimeout 等
原文连接
ECMA262 Job Queues
HTML Standard Task Queue
HTML系列:macrotask和microtask
microtask and macrotask a hands on approach
difference-between-microtask-and-macrotask-within-an-event-loop-context
公众号:码力全开