1. 程式人生 > >ES6 async/await在專案中的應用

ES6 async/await在專案中的應用

最近在專案中有這麼一個需求,當用戶使用積分去兌換某個商品之後,點選某個按鈕會呼叫兩個介面,其中先呼叫一個介面,從介面中獲取record_id之後,再呼叫另外一個介面,將獲得的record_id傳遞到第二個介面中,然後從第二個介面返回goods_name,那麼我們來看一下用以前的方式和使用ES6的async/await方式來編寫的不同。
一開始,我使用的方式如下

apis.postExchangeGoods({},{goods_id: this.current_goods.id})
  .then(res => {
    if (res.data.errcode === 0) {
      let
record_id = res.data.record_id; apis.postUserInfo({},{record_id: record_id}) .then(res => { this.show = false; let goods_name = res.data.goods_name; this.$router.push({ name: 'xxx' }); }); }); } });

可以看到這種方式下,在一個介面的回撥中呼叫另一個介面,程式碼不僅多,看起來也比較雜亂,而且此時只是呼叫2個介面,如果在某些需求下我們要呼叫四五個介面甚至十個介面,那麼此時程式碼不僅看起來特別亂,而且會各種回撥介面的巢狀,維護起來也不方便,掉入傳說中的callback hell。而es6中推出async/await函式就可以解決這種問題,我們來看一下使用這種方式後寫出來的程式碼:

1.async function postUserInfo() {
2.  try {
3.    var result1 = await window.apis.postExchangeGoods({}, {goods_id: _this.goods_id});
4.    var result2 = await window.apis.postUserInfo({},{record_id:resul1.data.rescord_id});
5.    return result2.data.goods_name;
6.  } catch(e) {
7.    console.log(e);
8.
} 9.} 10.postUserInfo().then((goods_name) => { 11. this.$router.push({ 12. name: 'xxx' 13. }); 14.});

第二種寫法需要使用async function去定義一個方法,那麼這個方法最後會返回一個Promise物件。
在這個方法中呼叫那兩個介面,第3行程式碼中使用了await命令,那麼此時該方法會等待第3行的非同步操作執行完畢之後,才會繼續執行下面的程式碼,如果由於網路問題該postExchangeGoods請求了5秒,那麼程式碼就會在這裡等待5秒,直到獲取返回結果,然後再執行下面的程式碼。

當async方法裡面的內容全部執行完畢之後,就會呼叫第10行中的then指定的回撥方法。

需要注意的是:await後面跟著的函式,必須通過Promise.resolve或者Promise.reject來返回某些內容

我們對比一下這兩種寫法,可以看得出,第二種方法首先程式碼比較簡潔,呼叫兩個介面只寫了第3行和第4行程式碼,然後用一個變數來獲取返回的結果。而且更重要的是,他脫離了第一種寫法的那種幾個回撥函式巢狀的現象,程式碼變得更清晰,維護起來也更好。當然,由於async/await是es6中推出的API,使用babel並不能將其轉譯為大部分瀏覽器支援的ES5,此時我們需要使用墊片。