1. 程式人生 > 程式設計 >JS非同步巨集佇列與微佇列原理區別詳解

JS非同步巨集佇列與微佇列原理區別詳解

1. 原理圖

JS非同步巨集佇列與微佇列原理區別詳解

2. 說明

JS 中用來儲存待執行回撥函式的佇列包含 2 個不同特定的列隊

  • 巨集列隊:用來儲存待執行的巨集任務(回撥),比如:定時器回撥、DOM 事件回撥、ajax 回撥
  • 微列隊:用來儲存待執行的微任務(回撥),比如:promise的回撥、MutationObserver 的回撥

JS 執行時會區別這 2 個佇列

  • JS 引擎首先必須先執行所有的初始化同步任務程式碼
  • 每次準備取出第一個巨集任務執行前,都要將所有的微任務一個一個取出來執行,也就是優先順序比巨集任務高,且與微任務所處的程式碼位置無關

下面這個例子可以看出Promise要先於setTimeout執行:

setTimeout(() => { //立即放入巨集佇列
   console.log('timeout callback1()')
   Promise.resolve(3).then(
    value => { //立即放入微佇列
     console.log('Promise onResolved3()',value)
    }
   )
  },0)

  setTimeout(() => { //立即放入巨集佇列
   console.log('timeout callback2()')
  },0)

  Promise.resolve(1).then(
   value => { //立即放入微佇列
    console.log('Promise onResolved1()',value)
    setTimeout(() => {
     console.log('timeout callback3()',value)
    },0)
   }
  )

  Promise.resolve(2).then(
   value => { //立即放入微佇列
    console.log('Promise onResolved2()',value)
   }
  )

  // Promise onResolved1() 1
  // Promise onResolved2() 2
  // timeout callback1()
  // Promise onResolved3() 3
  // timeout callback2()
  // timeout callback3() 1

3. 相關題目

程式碼一:

// 3 7 4 1 2 5
  /*
  巨集: []
  微: []
  */
  const first = () => (new Promise((resolve,reject) => {
   console.log(3)
   let p = new Promise((resolve,reject) => {
    console.log(7)
    setTimeout(() => {
     console.log(5)
     resolve(6) //會被忽略,因為會先執行微佇列裡的resolve(1),此時狀態已經改變過了,且狀態只能改變一次
    },0)
    resolve(1)
   })
   resolve(2)
   p.then((arg) => {
    console.log(arg)
   })
  }))

  first().then((arg) => {
   console.log(arg)
  })
  console.log(4)

程式碼二:

// 1 7 2 3 8 4 6 5 0   
  setTimeout(() => {
   console.log("0")
  },0)
  new Promise((resolve,reject) => {
   console.log("1")
   resolve()
  }).then(() => {
   console.log("2")
   new Promise((resolve,reject) => {
    console.log("3")
    resolve()
   }).then(() => {
    console.log("4")
   }).then(() => {
    console.log("5")
   })
  }).then(() => {
   console.log("6")
  })

  new Promise((resolve,reject) => {
   console.log("7")
   resolve()
  }).then(() => {
   console.log("8")
  })

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。