宏任务和微任务

介绍这个之前, 建议先了解一下事件循环

宏任务 (Macrotask)

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

比如: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering

微任务 (Microtask)

微任务则是为了完成一些更新应用程序状态的较小的任务,如处理 Promise 的回调和 DOM 的修改,以便让这些任务在浏览器重新渲染之前执行

微任务应该以异步的方式尽快执行, 所以它的开销比宏任务小, 并且可以在 UI 重新渲染之前执行, 避免了不必要的 UI 渲染

比如: process.nextTick, Promises, Object.observe, MutationObserver

运行机制

  • 执行一个宏任务 (栈中没有就从事件队列中获取)
  • 执行过程中如果遇到微任务, 就将它添加到微任务的任务队列中
  • 宏任务执行完毕后, 立即执行当前微任务队列中的所有微任务 (依次执行)
  • 当前宏任务执行完毕, 开始检查渲染, 然后GUI线程接管渲染
  • 渲染完毕后, JS线程继续接管, 开始下一个宏任务 (从事件队列中获取)