await、return 和 return await 的陷阱

摘要:await、return 和 return await 有很多容易被忽视的不同之处。 await waitAndMaybeReject() 的结果,如果 rejected,我们的 catch 块捕获了异常

await、return 和 return 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

永远不会返回 "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';
  }
}

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_11123