停止像這樣使用 "async/await",改用原版

前端小智 發表於 2022-06-23
人工智慧

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

最近我看到一些開發者使用這種方法來處理 async/await 錯誤。

/**
 * @param { Promise } promise
 * @param { Object= } errorExt - Additional Information you can pass to the err object
 * @return { Promise }
 */
function to(promise, errorExt) {
  return promise
    .then((data) => [null, data])
    .catch((err) => {
      if (errorExt) {
        const parsedError = Object.assign({}, err, errorExt);
        return [parsedError, undefined];
      }
      return [err, undefined];
    });
}

async function doSomething() {
  const [error1, result1] = await to(fetch(''));
  if (error1) {
    return;
  }

  const [error2, result2] = await to(fetch(result1));
  if (error2) {
    return;
  }
  // ...
}

正如你所看到的,他們把函式包起來,把原來的Promise轉換成一個肯定會成功的 "Promise",並返回一個陣列。

如果原始的Promise成功了,那麼陣列中的第一項是空的,表示沒有錯誤,第二項是原始 Promise的結果。如果原來的Promise失敗了,那麼陣列的第一項是錯誤,第二項是未定義。就是這樣了。

他們認為這很優雅,使程式碼更易讀。但我不這麼認為,我也不建議這樣使用它

我認為這樣的封裝有點過度,在大多數情況下,不需要這樣做。接下來,我將從兩個角度說明我的觀點。

1. 從設計的角度來看

Async/await API的目的是允許開發者像寫同步程式碼一樣寫非同步程式碼。因此,可以使用try...catch來捕獲async/await錯誤。

而這樣的函式似乎為我們考慮到了一切,但其他剛看到你的程式碼的開發者總會有這樣的疑問。為什麼to函式返回的Promise所使用的await沒有用try...catch來包裝?

image.png

只有找到原始的to函式定義,並理解其意圖,你才能知道 "啊,原來to函式返回的 Promise 永遠不會被拒絕"。

所以它進一步增加了其他開發者的理解成本,使得熟悉的 async/await 變得不再 "熟悉"。

2. 從實用性的角度來看

to函式的主要使用情況是,在同一上下文中有多個await promises,而它們相應的錯誤處理方式是不同的。那麼就使用這個封裝函式對每個錯誤進行不同的處理,減少對try...catch的使用。

但在實際開發,在每個到函式之後,你需要使用if語句來確定是否有錯誤。這與使用try...catch的本意沒有什麼不同,都是為了檢查錯誤。

image.png

其次,在真實的生產環境中,下一個Promise依賴上一個Promise的情況並不少見。但重要的一點是,這兩個Promise通常是關聯函式。所以在外層使用try...catch來統一處理錯誤是沒有問題的。比如說

image.png

最後,在JavaScript中,大多數Promise場景都是在 Input/output上,比如網路IO和檔案IO。這些IO場景可以將攔截器封裝在下層,並根據錯誤程式碼統一處理。例如,使用axios攔截器。

image.png

所以它可能並不像預期的那樣實用。也就是說,它可能只用於整個專案的一小部分,而且成本超過了收益。

這就是我所有的觀點,你怎麼看?你贊成這種做法嗎?

編輯中可能存在的bug沒法實時知道,事後為了解決這些bug,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug


作者:Marina Mosti 譯者:前端小智 來源:medium

原文:https://blog.bitsrc.io/stop-u...

交流

文章每週持續更新,可以微信搜尋「 大遷世界 」第一時間閱讀和催更(比部落格早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了很多我的文件,歡迎Star和完善,大家面試可以參照考點複習,另外關注公眾號,後臺回覆福利,即可看到福利,你懂的。

停止像這樣使用 "async/await",改用原版