宏任务和微任务

本文最后更新于:32 分钟前

宏任务和微任务

js 代码执行顺序,先同步任务,异步任务进入事件列表(Event Table)并注册回调函数,等待指定的事件完成时,事件列表会将这个回调函数移入事件队列(Event Queue)/任务队列(Task Queue)
任务队列被细分为两个,
macro-task(宏任务)队列
micro-task(微任务)队列
QQ截图20220929102542.png

1.微任务是用于插队的 2.微任务是快于宏任务的,但是一般是由宏任务<script>开始执行。

注:为什么说微任务是用于插队的呢?因为每次执行宏任务之前都会看有没有微任务,不管微任务是何时加入队列的,都会清空微任务队列之后才会执行下一个宏任务

3.微任务>dom 渲染>宏任务

1)main script 中的代码优先执行(编写的顶层 script 代码);
2)在执行任何一个宏任务之前(不是队列,是一个宏任务),都会先查看微任务队列中是否有任务需要执行
3)也就是宏任务执行之前,必须保证微任务队列是空的;
4)如果不为空,那么优先执行微任务队列中的任务(回调)

宏任务

  • script(整体代码)
  • setTimeout、setInterval
  • setImmediate
  • I/O (比如 Ajax 操作从网络读取数据)
  • UI render

微任务

  • process.nextTick
  • Promise 本身是同步,Promise.then、.catch 和 .finally 等方法是异步
  • Async/Await
  • MutationObserver(html5 新特性)

执行顺序

经典面试题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
setTimeout(() => {
console.log(1)
}, 0)

new Promise(resolve => {
console.log(2)
resolve()
}).then(() => {
console.log(3)
})

console.log(4)
// 2
// 4
// 3
// 1

第一步:
会先去查找是否有同步任务?这里面的同步任务有第 6 行和第 12 行 ,因为在我们 new 一个 Promise 时会同步执行里面的 log 语句,所以这个会变成一个同步任务,又因为 js 执行机制会从上到下所以第 6 行会是第一个打印出来,然后就是第 12 行的同步任务。

第二步:
会去查找异步任务中是否有待执行的微任务,这里面的第 9 行刚好是一个待执行的微任务,所以它会第三个打印出来。当异步任务里面的所有微任务都执行完之后,会去查找宏任务里面的符合条件的宏任务,这里就会执行第 2 行代码。

第三步:
当所有异步任务结束之后,又会进行下一次大循环。