#每日一記# 1分鐘學會如何「便利地」使用 async/await

羅小黑寫寫文字發表於2019-02-20
每日一記 - 但並不日更

導讀

首先值得肯定的是在非同步程式碼組織中 async/await 確實起到了很棒的作用,書寫程式碼更加流暢。尤其是在作用域的處理上,讓非同步返回值非同步函式呼叫時的作用域保持相同。

// es5
// 假設 bar 函式返回一個有效的 promise
function foo () {
  return bar().then(res => {
    console.log(res); // 1
  })

  console.log(res); // error
}
複製程式碼
// es7
// 假設 bar 函式返回一個有效的 promise
async function foo () {
  let res = await bar();
  console.log(res); // 1
}
複製程式碼

在相同的作用域下可以呼叫非同步返回值,這樣的程式碼閱讀起來更加符合直覺。

但在異常處理的時候,async/await 卻變得異常複雜,本文就講討論如何儘可能優雅的優化這個問題。

異常處理

所謂成也蕭何敗也蕭何,在 async/await 異常處理的時候需要引入 try/catch 來解決程式異常或者 reject但這又引入了一個子作用域干擾了程式碼的流暢性,更正:引入作用域的不是 try/catch 而是 let

我們來看一點程式碼,我將展示 try/catch let 是如何隱式的建立了一個新的作用域。

// es7
try {
  let a = true;
} catch (e) {
  let a = false;
}

console.log(a);

// ⬇編譯後
// es5
"use strict";

try {
  var _a = true; // 實際上 try catch 的花括號內是子作用域
} catch (e) {
  var _a2 = false;
}

console.log(a); // error
複製程式碼

因為 try/catch let 有隱式建立作用域的特性,這會讓在花括號中申明的變數無法被外部訪問到,這很容易讓程式碼容易出錯,並且書寫起來很不流暢。

下面就是應用了 try/catchasync/await 函式。

// es7
// 假設 bar 函式返回一個有效的 promise
async function foo () {
  let res, err;
  
  try {
    res = await bar();
  } catch (e) {
    err = e;
  }

  if (err) {
    return `error occur`;
  }

  return res;
}
複製程式碼

利用解構

既然 try/catch 的作用域令人頭疼,那麼我們也可以利用 es6 中解構的特性來優化一下程式碼。

// es7
// 假設 bar 函式返回一個有效的 promise
async function foo () {
  let [err, res] = await to(bar());

  if (err) {
    return `error occur`;
  }

  return res;
}

function to (promise) {
  return promise
  .then(res => {
    return [null, res];
  })
  .catch(err => {
      return [err];
  })
}
複製程式碼

函式 to 幫我們把 promise 按照一個標準的格式返回一個陣列,而這個陣列最終都會使 promise 進入 resolve 狀態,因此就可以避免使用 try/catch 結構。

如果在專案中,可以把函式 to 單獨封裝成一個模組使用。

// to.js
export default function to (promise) {
  return promise
  .then(res => {
    return [null, res];
  })
  .catch(err => {
      return [err];
  })
}
複製程式碼

這篇文章是對 如何不用 try/catch 還能優雅使用 async/await (英文且需科學上網)這篇文章的實踐和解讀。

羅小黑寫寫文字

如果喜歡文章 請留下一個贊~
如果喜歡文章 分享給更多人~

掘金中關注我
簡書中關注我

自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證
轉載時請保留原文連結 以保證可及時獲取對文章的訂正和修改

相關文章