'return await promise' 與 'return promise' 這細微的區別

前端小智發表於2022-06-03
本文首發於微信公眾號:大遷世界, 我的微信:qq449245884,我會第一時間和你分享前端行業趨勢,學習途徑等等。
更多開源作品請看 GitHub https://github.com/qq449245884/xiaozhi ,包含一線大廠面試完整考點、資料以及我的系列文章。

當從一個非同步函式的promise返回時,我們可以使用return await promise等待 promise 解析完,也可以直接返回它 return promise

async function func1() {
  const promise = asyncOperation();
  return await promise;
}

// vs

async function func2() {
  const promise = asyncOperation();
  return promise;
}

這兩個表示式都是有效的。然而,在某些情況下,這些表示式的表現會有所不同嗎?我們往下看。

1. 相同的行為

為了找到這兩個表示式(返回 await promise vs return promise)之間的區別,我們需要一個輔助函式 delayedDivide(n1, n2)

該函式除2個數字,並返回包含在promise中的除法結果:

function promisedDivision(n1, n2) {
  if (n2 === 0) {
    return Promise.reject(new Error('Cannot divide by 0'));
  } else {
    return Promise.resolve(n1 / n2);
  }
}

如果第二個引數(除數)是 0,該函式返回一個 reject,因為除以 0 是不可能的。

定義了輔助函式之後,我們來跑幾個例子。

下面的函式divideWithAwait()使用return await promisedDivision(6,2)表示式來返回包裹在promise中的 6 除以 2 的除法

async function divideWithAwait() {
  return await promisedDivision(6, 2);
}

async function run() {
  const result = await divideWithAwait();
  console.log(result); // logs 3
}
run();

事例地址:https://codesandbox.io/s/with...

run()函式中,await divideWithAwait()表示式的計算結果為除法結果 3,一切正常。

如果有返回不帶await關鍵字,結果又會怎麼樣呢?

async function divideWithoutAwait() {
  return promisedDivision(6, 2);
}

async function run() {
  const result = await divideWithoutAwait();
  console.log(result); // logs 3
}
run();

事例地址:https://codesandbox.io/s/with...

即使在divideWithoutAwait() 中沒有使用 await 關鍵字,run() 函式中的表示式awaitdivideWithoutAwait() 的結果也是正確的。

在這一步,我們已經看到使用return await promisereturn promise並沒有什麼不同。

2.不同行為

現在我們採用另一種方法,要使函式 promisedDivision(n1, n2)返回一個被拒絕的promise,我們將第二個引數設定為 0

因為promisedDivision(n1, 0) 會返回一個異常,我們使用 try {... } catch (error) {...}

async function divideWithAwait() {
  try {
    return await promisedDivision(5, 0);
  } catch (error) {
    // Rejection caught
    console.log(error); // logs Error('Cannot divide by 0')
  }
}

async function run() {
  const result = await divideWithAwait();
}
run();

事例地址:https://codesandbox.io/s/with...

如果沒有 await,結果又會怎麼樣?

async function divideWithoutAwait() {
  try {
    return promisedDivision(5, 0);
  } catch (error) {
    // Rejection NOT caught
    console.log(error);
  }
}

async function run() {
  const result = await divideWithoutAwait();
}
run(); // Uncaught Error: Cannot divide by 0

事例地址:https://codesandbox.io/s/with...

然而,這次,catch(error) { ... }並沒有捕捉到異常。

到這,我們就使用return await promisereturn promise之間的主要區別了。

~完,我是刷碗智,我要去 SPA 了,我們下期見!


作者:Dmitri Pavlutin 譯者:前端小智 來源:Dmitri Pavlutin

原文:https://dmitriplutin.com/retu...

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

交流

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

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

相關文章