浏览器里的微任务和宏任务是什么?

浏览器中并不存在宏任务( Macrotask ), 宏任务是 Node.js 发明的术语
浏览器中只有任务( Task )和微任务( Microtask )

  1. 使用 script 标签、setTimeout 可以创建任务
  2. 使用 Promise.then, window.queueMicrotask, MutationObserver, Proxy 可以创建微任务

微任务会在任务间隙执行( 插队执行 )
微任务队列执行完才会执行任务队列

看下面的示例,输出结果是什么呢?

  1. Promise.resolve()
  2. .then(() => {
  3. console.log(0)
  4. return Promise.resolve(4)
  5. })
  6. .then((res) => { console.log(res)})
  7. Promise.resolve()
  8. .then(() => console.log(1))
  9. .then(() => console.log(2))
  10. .then(() => console.log(3))
  11. .then(() => console.log(5))
  12. .then(() => console.log(6))

一个 return Promise 等价于 2个 Promse.then

  1. Promise.resolve()
  2. .then(() => {
  3. console.log(0)
  4. })
  5. .then(() => {
  6. Promise.resolve().then(() => {
  7. Promise.resolve().then(() => console.log(4))
  8. }
  9. )
  10. })
  11. Promise.resolve()
  12. .then(() => console.log(1))
  13. .then(() => console.log(2))
  14. .then(() => console.log(3))
  15. .then(() => console.log(5))
  16. .then(() => console.log(6))
  • 连续的.then必须一个 .then 完成后才能把下一个.then 放入next 队列
  • 同级的 .then 可以同时放入 next 队列

队列变化如下:

  1. console.log(0) 和 console.log(1) 入队:[0, 1]
  2. 0 出队,x(y(4)) 入队; 1 出队,2 入队: [x(y(4)), 2]
  3. x(y(4)) 出队,y(4) 入队;2 出队,3 入队: [y(4), 3]
  4. y(4) 出队,4 入队;3 出队,5 入队:[4, 5]
  5. 4 出队5 出队,6 入队: [6]
  6. 6 出队

故输出顺序为:0,1,2,3,4,5,6