初探ES7中的 async、await

任意一個名稱都是有意義的,先從字面意思來理解。async 是“異步”的簡寫,而 await 可以認爲是 async wait 的簡寫。所以應該很好理解 async 用於申明一個 function 是異步的,而 await 用於等待一個異步方法執行完成。

另外還有一個很有意思的語法規定,await 只能出現在 async 函數中。然後細心的朋友會產生一個疑問,如果 await 只能出現在 async 函數中,那這個 async 函數應該怎麼調用?

如果需要通過 await 來調用一個 async 函數,那這個調用的外面必須得再包一個 async 函數,然後……進入死循環,永無出頭之日……

如果 async 函數不需要 await 來調用,那 async 到底起個啥作用?

async 起什麼作用

這個問題的關鍵在於,async 函數是怎麼處理它的返回值的!

我們當然希望它能直接通過 return 語句返回我們想要的值,但是如果真是這樣,似乎就沒 await 什麼事了。所以,寫段代碼來試試,看它到底會返回什麼:

async function testAsync() {
    return "hello async";
}

const result = testAsync();
console.log(result);

看到輸出就恍然大悟了——輸出的是一個 Promise 對象。

 

await 到底在等啥

一般來說,都認爲 await 是在等待一個 async 函數完成。不過按語法說明,await 等待的是一個表達式,這個表達式的計算結果是 Promise 對象或者其它值(換句話說,就是沒有特殊限定)。

因爲 async 函數返回一個 Promise 對象,所以 await 可以用於等待一個 async 函數的返回值——這也可以說是 await 在等 async 函數,但要清楚,它等的實際是一個返回值。注意到 await 不僅僅用於等 Promise 對象,它可以等任意表達式的結果,所以,await 後面實際是可以接普通函數調用或者直接量的。所以下面這個示例完全可以正確運行。

 

代碼:

function fn01 () {
        // 加載用戶角色
        return new Promise((resolve, reject) => {
          _this.$https.get('api/*******').then((response) => {
            console.log('執行fn01');
            resolve();
          }).catch(function (error) {
            console.log(error);
          });
        });
      };

      function fn02 () {
        // 設置用戶頂級組織
        return new Promise((resolve, reject) => {
          _this.$https.post('api/*******').then((response) => {
            console.log('執行fn02');
            resolve();
          }).catch(function (error) {
            console.log(error);
          });
        });
      };

      // 公共設置部分

      function fn03 () {
        // 獲取菜單控制權限
        return new Promise((resolve, reject) => {
          _this.$https.get('api/*******' + _this.$route.query.mid).then((response) => {
            console.log('執行fn03');
            resolve();
          }).catch(function (error) {
            console.log(error);
          });
        });
      };

      async function action () {
        await fn03();
        await fn02();
        await fn01();
        return '執行到最後了';
      };
      action().then(val => {
        alert(val);
      });

 

結果:

如果項目過程中要控制異步執行的順序,其實通過Promise.all放法也可以達到類似的效果,如下

Promise.all([fn01(), fn02(), fn03()]).then(result => console.log(result)).catch(e => console.log(e));

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章