JS異步--async,await,promise,setTimeout 執行順序

問題:

在JavaScript的異步代碼執行時:promise

  1. 若是遇到await,就將await執行後,後面的代碼放入等待隊列(由於async和await的本質仍是promise的運用,返回的是一個promise對象)。bash

    備註:async是generator的語法糖, 只是把generator的function後面的*換成了前面的async,把yield換成了await。運行原理是同樣的,都是爲了解決JS的異步操做問題,畢竟JS是單線程的。異步

  2. 若是遇到promise的then和catch,也一樣放入等待隊列,兩者優先級相同,在同步代碼結束後按照隊列的先入先出原則執行。async

  3. 若是遇到setTimeout的話,也是一樣放在等待隊列,可是是不一樣的等待隊列,優先級低於await和promise。函數

代碼證實:

async function async1() {
    console.log("async1 start");
    await  async2();  // 關鍵點1
    console.log("async1 end");
}
async  function async2() {
    console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
    // 關鍵點2
    console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
    console.log("promise1");
    // 關鍵點3
    resolve();
}).then(function () {
    console.log("promise2");
});
console.log('script end');
複製代碼

以上代碼片斷的執行結果爲:ui

> "script start"
> "async1 start"
> "async2"
> "promise1"
> "script end"
> "async1 end"
> "promise2"
> "settimeout"
複製代碼

解釋:

----------------------------------------- 同步代碼部分 --------------------------------------------spa

  1. 代碼運行從同步操做console.log("script start");開始,遇到setTimeout直接丟到等待隊列的最末端(實際上是另外一個優先級較低的等待隊列的隊首,姑且認爲是promise等待隊列的最末端)。
  2. 執行async1函數,其中的console.log("async1 start");爲同步代碼,直接輸出,而後遇到了await async2
  3. 進入async2函數內部,執行其中包含的同步代碼console.log( 'async2');,在執行事後立刻將await後面的代碼所有放到promise等待隊列中。
  4. 接着尋找同步代碼,發現promise中的console.log("promise1");爲同步代碼,當即執行。而後發現這個promise後面緊跟真一個then(),不要猶豫直接將這個promise放入剛剛已經存放了await的等待隊列中。
  5. 最後一個同步代碼console.log('script end');被找到並執行。

----------------------------------------- 異步代碼部分 --------------------------------------------線程

如今的異步代碼等待隊列中,包含await函數後面的全部代碼,和promise的then()code

  1. 先執行await async2後面的代碼console.log("async1 end");
  2. 在執行promise中的then()中的resolve代碼console.log("promise2");
  3. 最後執行setTimeout代碼console.log("settimeout");

√到此爲止全部代碼執行完畢。對象

相關文章
相關標籤/搜索