1. 程式人生 > 其它 >JS 事件迴圈機制(巨集任務、微任務)

JS 事件迴圈機制(巨集任務、微任務)

執行程式碼的先後順序:

先 主任務 後 任務佇列。

任務佇列又分:巨集任務(task)、微任務(Microtasks)

  • 微任務(Microtasks)-> Promise.then 、process.nextTick
  • 巨集任務(task)-> 整體程式碼<script/>、ajax、定時器(比如:setTimeout)、事件(比如:onclick)、requestAnimationFrame(幀動畫)、I/O(檔案操作)、UI rendering(樣式渲染)

任務佇列既有巨集任務又有微任務,先執行微任務,再執行巨集任務。

  1.主任務(主執行緒)-> 2. 微任務(清空一次) -> 3.巨集任務(每執行一個清空一次微任務)。

                  ↑_________迴圈執行_________|

這種迴圈機制叫做:任務迴圈(event loop)

主執行緒-微任務-巨集任務 練習:(如何使用async、await、Promise以及各種任務的執行特點)

async function fn() {
  console.log(1);
  let b = await fn2();//b拿到return的值 = resolve()裡面的值,並阻塞下面的程式碼。
  console.log(b);
  console.log(2)//出現在await之後,也就是2一定跟著3之後出現
};
function fn2() {
  return new Promise((resolve, reject) => {//async、await要配合Promise使用。
      console.log(9);
      setTimeout(() => {
          resolve(3)//進入巨集任務,定時器誰先觸發誰先執行。
      }, 1000)
  });
}
// async function fn() {
//     //function fn() {
//     console.log(1);
//     let b = await fn2();
//     console.log(2)//進入微任務,誰先進入誰先觸發。
// };
// function fn2() {
//     console.log(9);
//     setTimeout(() => {
//         resolve(3)//進入巨集任務,定時器誰先觸發誰先執行。
//     }, 1000)
// };

setTimeout(() => {
  console.log(6)//進入巨集任務
}, 500);
fn()
let a = new Promise((resolve, reject) => {
  console.log(4);
  resolve()
})
a.then(() => {
  console.log(5)//進入微任務
});
//fn()
console.log(8);
//1,9,4,8,2,5,3,6
//4,1,9,8,5,2,3,6
//注:如果await後面的函式,沒有被Promise包著。 await 下面的程式碼會進微任務佇列(誰先進入誰先執行),定時器會進巨集任務佇列(誰先觸發誰先執行)。
//1,9,4,8,5,6,3,2
//await後面的函式被Promise包著,那麼await後面的函式才會阻塞下面的函式,等await後面的函式執行完,再往下執行(只在函式體內發生)。