浅析 JS 事件循环之 Microtask 和 Macrotask

简介

咱们在上一篇 《浅析 JS 中的EventLoop 事件循环》 中提到一个 Event Queue,其实在事件循环中 queue 一共有两种,还有一种叫 Job Queuehtml

其中git

Event Queue 在 HTML 规范中被称为 Task Queue,可是为了区分,通常都叫做 Macrotask Queue
Job Queue 是在 ECMAScript 规范中谈及处理 Promise 回调时提到的,可是因为和 V8 中的实现比较类似,因此通常都称为 Microtask Queue

Macrotask

Macrotasks 包含了解析 HTML、生成 DOM、执行主线程 JS 代码和其余事件如 页面加载、输入、网络事件、定时器事件等。从浏览器的角度,Macrotask 表明的是一些离散的独立的工做。github

常见应用
setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI renderingweb

Microtask

Microtasks 则是为了完成一些更新应用程序状态的较小的任务,如处理 Promise 的回调和 DOM 的修改,以便让这些任务在浏览器从新渲染以前执行。Microtask 应该以异步的方式尽快执行,因此它们的开销比 Macrotask 要小,而且可使咱们在 UI 从新渲染以前执行,避免了没必要要的 UI 渲染。api

常见应用
process.nextTick, Promises, Object.observe, MutationObserverpromise

执行顺序

Event Loop 的实现须要至少一个 Macrotask Queue 和至少一个 Microtask Queue。为了便于理解,咱们都简化成一个。
简单来讲,Microtask Queue 具备更高的优先级,即执行一个 Macrotask 任务后,就会清空整个 Microtask Queue,此时若是有新的 Microtask 加入也会被执行。浏览器

因此咱们来看下面的代码:
图片描述网络

执行顺序是什么?
咱们已经知道 setTimeout 是 Macrotask,Promise 是 Microtask,而这段代码从上到下执行也是一个 Macrotaskapp

步骤:webapp

  1. 开始执行,执行脚本做为一个任务进入 Macrotask Queue,同时进入调用栈执行
  2. Line 1, 输出 script start
  3. Line 3 的 setTimeout 回调进入 Macrotask Queue 等待
  4. Line 7 的回调进入 Microtask Queue 等待
  5. Line 13 输出 script end,此时脚本执行完成(即完成了一个 Macrotask)
  6. 开始执行 Microtask Queue,从中拿出一个放入调用栈执行
  7. 开始执行 Line 7 的回调,该回调输出 promise1,返回 undefined
  8. Line 9 的回调进入 Microtask Queue,因为 Microtask Queue 没有清空,直接执行该回调,输出 promise2,该回调返回 undefined
  9. Microtask Queue 已清空(此时浏览器能够更新渲染UI),开始将 Macrotask Queue 中任务放入调用栈执行
  10. 执行 Line 3 的回调,输出 setTimeout,Macrotask Queue 清空
  11. 程序执行完成

因此打印顺序为:

script start -> script end -> promise1 -> promise2 -> setTimeout

PS. 上面的这段代码执行流程,建议看原文的倒数第二篇参考文章,有动态交互操做能够演练。

总结

microtask-macrotask.png

  1. Microtask 相比 Macrotask 具备更高的优先级
  2. Macrotask 老是在 JS 代码执行完成而且 Microtask Queue 清空以后执行
  3. JS 代码执行自己也是一个 Macrotask
  4. Microtask Queue 清空后有可能会从新渲染 UI
  5. Promise 属于 Microtask,setTimeout 属于 Macrotask

整体的执行顺序为:常规代码 -> 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

公众号:码力全开
bVbrEUH?w=258&h=258

相关文章
相关标签/搜索