await、return 和 return await 的陷阱

justjavac發表於2017-12-11

本文閱讀時間大概 2 分鐘


awaitreturnreturn await 有很多容易被忽視的不同之處。

首先定義一個非同步函式:

async function waitAndMaybeReject() {
  // 等待1秒
  await new Promise(r => setTimeout(r, 1000));

  const isHeads = Boolean(Math.round(Math.random()));

  if (isHeads) {
    return 'yay';
  } else {
    throw Error('Boo!');
  }
}
複製程式碼

函式等待 1 秒鐘,然後有一半的概率返回 "yay",一半的概率丟擲異常。

1 直接呼叫 Just calling

async function foo() {
  try {
    waitAndMaybeReject();
  }
  catch (e) {
    return 'caught';
  }
}
複製程式碼

直接呼叫 foo,函式總是返回 Promise fulfill with undefined, without waiting

await、return 和 return await 的陷阱

永遠不會返回 "yay"

2 Awaiting

async function foo() {
  try {
    await waitAndMaybeReject();
  }
  catch (e) {
    return 'caught';
  }
}
複製程式碼

呼叫 foo,函式返回的 Promise 等待 1 秒,然後 fulfill with undefined, or fulfill with "caught"

因為我們 await waitAndMaybeReject() 的結果,如果 rejected,我們的 catch 塊捕獲了異常,然後 "caught",如果 fulfilled,我們的函式並沒有返回 Promise 的值。

3 Returning

async function foo() {
  try {
    return waitAndMaybeReject();
  }
  catch (e) {
    return 'caught';
  }
}
複製程式碼

呼叫 foo,函式返回的 Promise 等待 1 秒,然後 fulfill with "yay", or reject with Error('Boo!')

4 Return-awaiting

async function foo() {
  try {
    return await waitAndMaybeReject();
  }
  catch (e) {
    return 'caught';
  }
}
複製程式碼

呼叫 foo,函式返回的 Promise 等待 1 秒,然後 fulfill with "yay", or fulfill with "caught"

這個是最符合我們預期的寫法。

我們可以把它拆分一下:

async function foo() {
  try {
    // 等待 waitAndMaybeReject() 函式的結果
    // 把 fulfilled value 賦值給 fulfilledValue:
    const fulfilledValue = await waitAndMaybeReject();
    // 如果 waitAndMaybeReject() 失敗,丟擲異常:
    return fulfilledValue;
  }
  catch (e) {
    return 'caught';
  }
}
複製程式碼

dev-reading/fe 是一個閱讀、導讀、速讀的 repo,不要依賴於 dev-reading/fe 學習知識。本 repo 只是一個快速瞭解文章內容的工具,並不提供全文解讀和翻譯。你可以通過本平臺快速瞭解文章裡面的內容,找到感興趣的文章,然後去閱讀全文。

閱讀原文:await vs return vs return await

討論地址:await、return 和 return await 的陷阱 #12

如果你想參與討論,請點選這裡

相關文章