js 異步執行順序


參考文章:   js 異步執行順序
 
1.js的執行順序,先同步后異步
2.異步中任務隊列的執行順序: 先微任務microtask隊列,再宏任務macrotask隊列
3.調用Promise 中的resolve,reject屬於微任務隊列,setTimeout屬於宏任務隊列
注意以上都是 隊列,先進先出。
 
微任務包括 `process.nextTick` ,`promise` ,`MutationObserver`。
宏任務包括 `script` , `setTimeout` ,`setInterval` ,`setImmediate` ,`I/O` ,`UI rendering`。
 
題目1:
console.log('script start')  
async function async1() {
  await async2()
  console.log('async1 end') 
}
async function async2() {
  console.log('async2 end')
}
async1()

setTimeout(function() {
  console.log('setTimeout') 
}, 0)

new Promise(resolve => {
  console.log('Promise') 
  resolve()
})
.then(function() {
  console.log('promise1') 
})
.then(function() {
  console.log('promise2') 
})

console.log('script end') 

執行結果?

分析:

首先執行 同步代碼:

1. 首先執行    console.log('script start')
2. 執行 async1() 的時候,馬上執行了 async2函數:console.log('async2 end')
3. 順序執行 new Promise()中的同步函數:console.log('Promise')
4. 最后執行  console.log('script end')。
上面是同步執行的代碼,然后看剩下的異步執行的代碼:
首先,setTimeout是 宏觀任務,排除到最后,剩下微觀任務:
async function async1() {
  await async2()
  console.log('async1 end') 
}
new Promise(resolve => {
  resolve()
})
.then(function() {
  console.log('promise1') 
})
.then(function() {
  console.log('promise2') 
})

5. 然后根據先入先出的對列方式,先執行  await async2() 后面阻礙的函數  console.log('async1 end') 

6. 執行promise的resolve函數

new Promise(resolve => {
  resolve()
})

也就是接下來的兩個then: console.log('promise1') ----  console.log('promise2') ;

7. 最后執行的是 setTimeout函數  console.log('setTimeout') ;

綜上所述,以上代碼執行的順序是:

1.script start 2.async2 end 3.Promise 4.script end 5.async1 end 6.promise1 7.promise2 8.setTimeout

 

題目2:

(function() {

    setTimeout(() => {
        console.log(0);
    });

    new Promise(resolve => {
        console.log(1);

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

        Promise.resolve().then(() => console.log(4));

    }).then(() => {
        console.log(5);
        Promise.resolve().then(() => console.log(8)); 
        setTimeout(() => console.log(6));
    });

    console.log(7);

})();

1. 同樣先執行同步代碼,且先把setTimeout去掉:

new Promise(resolve => {
      console.log(1);
      Promise.resolve().then(() => console.log(4)); //微觀任務
  }).then(() => {                  //then函數是執行對應的 resolve 的時候才執行的
      console.log(5);
      Promise.resolve().then(() => console.log(8));//微觀任務
}); console.log(7);

可以看出先執行: console.log(1);console.log(7);

2. 執行微任務  Promise.resolve().then(() => console.log(4)); 

代碼變成了:

(function() {
  setTimeout(() => {
      console.log(0);
  });
  new Promise(resolve => {
      setTimeout(() => {
          resolve();
          Promise.resolve().then(() => console.log(2));
          console.log(3);
      });
  }).then(() => {
      console.log(5);
      Promise.resolve().then(() => console.log(8)); //這句是多加的
      setTimeout(() => console.log(6));
  });
})();

只剩下宏觀任務(微觀任務在宏觀任務里,也就是宏觀任務外面不在有微觀任務了)

3. 執行  console.log(0);

4.再執行 new Promise 中的  setTimeout,先執行里面的同步函數:console.log(3)

5. 再執行上面的 resolve,對應的是下面的then函數:

then(() => {
      console.log(5);
      Promise.resolve().then(() => console.log(8)); //這句是多加的
      setTimeout(() => console.log(6));
 }

所以先執行 console.log(5);

剩下的都是微觀任務和宏觀任務,先看微觀任務:

 new Promise(resolve => {
      resolve();
      Promise.resolve().then(() => console.log(2));
  }).then(() => {
      Promise.resolve().then(() => console.log(8));
      setTimeout(() => console.log(6));
  });

所以根據隊列中的微觀任務順序先執行:console.log(2),在執行then中的 console.log(8);

最后再執行 console.log(6)

綜上所述,結果為 

1/7/4/0/3/5/2/8/6
 
詳細問題三:
(function() {
    setTimeout(() => {
        console.log(0);
    });

    new Promise(resolve => {

        console.log(1);
        
        setTimeout(() => {
            resolve();
            Promise.resolve().then(() => {
                console.log(2);
                setTimeout(() => console.log(3));
                Promise.resolve().then(() => console.log(4));
            });
        });

        Promise.resolve().then(() => console.log(5));

    }).then(() => {

        console.log(6);
        Promise.resolve().then(() => console.log(7));
        setTimeout(() => console.log(8));

    });

    console.log(9);
})();
解釋如下:【同步>異步;微任務>宏任務】
第一步:打印出 1、9 ;如圖

                    圖a

由圖a中的任務隊列可知:
第二步: 執行微任務3,打印出 5
第三步:執行宏任務1,打印出 0
第四步:開始執行宏任務2;如圖:

                              圖b

第五步:由圖b中的任務隊列可知, 執行微任務4,打印出 6,如圖:

                              圖c

第六步:由圖c中的任務隊列可知, 執行微任務5,打印出2;如圖 

                              圖d

由圖d的任務隊列可知,
第七步:執行微任務6,打印出7
第八步:執行微任務9,打印出4
第九步:執行宏任務7,打印出8;
第十步:執行宏任務8,打印出3;

即答案是:

1-9-5-0-6-2-7-4-8-3

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM