1. 程式人生 > >async/await學習筆記

async/await學習筆記

done odin 一次 做了 一場 req top resolv span

  async/await目的是簡化使用 promises 的寫法。

  讓我們來看看下面的例子:

// 一個標準的 JavaScript 函數
function getNumber1() {
    return Promise.resolve(‘374‘);
}
// 這個 function 做了和 getNumber1 同樣的事
async function getNumber2() {
    return 374;
}

  

  同樣,拋出異常的函數等於返回已失敗的 promises:

function f1() {
    return Promise.reject(‘Some error‘);
}
async function f2() {
    throw ‘Some error‘;
}

  

  關鍵字 await 只能使用在 async 的函數中,並允許你同步等待一個 Promise。如果我們在 async 函數之外使用 promise,我們仍然要用 then 回調函數:

async function loadData() {
    // `rp` 是一個請求異步函數
    var promise1 = rp(‘https://api.example.com/endpoint1‘);
    var promise2 = rp(‘https://api.example.com/endpoint2‘);
   
    // 現在,兩個請求都被觸發, 
    // 我們就等待它們完成。
    var response1 = await promise1;
    var response2 = await promise2;
    return response1 + ‘ ‘ + response2;
}
// 但,如果我們沒有在 `async function` 裏
// 我們就必須使用 `then`。
loadData().then(() => console.log(‘Done‘));

  區別:

  1. 幹凈的代碼: 使用 async/await 能夠讓你少寫代碼。每一次你使用 async/await 你都能跳過一些不必要的步驟:寫一個 .then,創建一個匿名函數來處理響應,在回調中命名響應,比如:
// `rp` 是一個請求異步函數
rp(‘https://api.example.com/endpoint1‘).then(function(data) {
 // …
});

  對比:

// `rp` 是一個請求異步函數
var response = await rp(‘https://api.example.com/endpoint1‘);
  1. 錯誤處理: Async/await 使得我們可以使用相同的代碼結構處理同步或者異步的錯誤 —— 著名的 try/catch 語句。
async function loadData() {
    try {
        var data = JSON.parse(await getJSON());
        console.log(data);
    } catch(e) {
        console.log(e);
    }
}
  1. 條件語句: 使用 async/await 來寫條件語句要簡單得多:
function loadData() {
  return getJSON()
    .then(function(response) {
      if (response.needsAnotherRequest) {
        return makeAnotherRequest(response)
          .then(function(anotherResponse) {
            console.log(anotherResponse)
            return anotherResponse
          })
      } else {
        console.log(response)
        return response
      }
    })
}

  對比:

async function loadData() {
  var response = await getJSON();
  if (response.needsAnotherRequest) {
    var anotherResponse = await makeAnotherRequest(response);
    console.log(anotherResponse)
    return anotherResponse
  } else {
    console.log(response);
    return response;    
  }
}

  

  1. 棧幀: 和 async/await 不同的是,根據promise鏈返回的錯誤堆棧信息,並不能發現哪出錯了。來看看下面的代碼:    
function loadData() {
  return callAPromise()
    .then(callback1)
    .then(callback2)
    .then(callback3)
    .then(() => {
      throw new Error("boom");
    })
}
loadData()
  .catch(function(e) {
    console.log(err);
// Error: boom at callAPromise.then.then.then.then (index.js:8:13)
});

  對比:

async function loadData() {
  await callAPromise1()
  await callAPromise2()
  await callAPromise3()
  await callAPromise4()
  await callAPromise5()
  throw new Error("boom");
}
loadData()
  .catch(function(e) {
    console.log(err);
    // 輸出
    // Error: boom at loadData (index.js:7:9)
});

  

  1. 調試: 如果你使用了 promises,你就會知道調試它們將會是一場噩夢。比如,你在 .then 裏面打了一個斷點,並且使用類似 “stop-over” 這樣的 debug 快捷方式,調試器不會移動到下一個 .then,因為它只會對同步代碼生效。而通過 async/await 你就可以逐步的調試 await 調用了,它就像是一個同步函數一樣。

 參考:  https://github.com/xitu/gold-miner/blob/master/TODO/how-javascript-works-event-loop-and-the-rise-of-async-programming-5-ways-to-better-coding-with.md

async/await學習筆記