使用 async/await 尝试/捕获块

新手上路,请多包涵

我正在深入研究节点 7 async / await 功能并不断绊倒这样的代码

 function getQuote() {
  let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit laborum.";
  return quote;
}

async function main() {
  try {
    var quote = await getQuote();
    console.log(quote);
  } catch (error) {
    console.error(error);
  }
}

main();

This seems to be the only possibility resolve / reject or return / throw with async / await 但是,v8 没有优化 try / catch 块中的代码?!

有替代品吗?

原文由 Patrick 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 454
2 个回答

备择方案

对此的替代方法:

 async function main() {
  try {
    var quote = await getQuote();
    console.log(quote);
  } catch (error) {
    console.error(error);
  }
}

会是这样的,明确使用承诺:

 function main() {
  getQuote().then((quote) => {
    console.log(quote);
  }).catch((error) => {
    console.error(error);
  });
}

或类似的东西,使用延续传递风格:

 function main() {
  getQuote((error, quote) => {
    if (error) {
      console.error(error);
    } else {
      console.log(quote);
    }
  });
}

原始示例

您的原始代码所做的是暂停执行并等待 getQuote() 返回的承诺解决。然后它继续执行并将返回的值写入 var quote 如果承诺已解决,则打印它,或者如果承诺被拒绝,则抛出异常并运行打印错误的 catch 块。

你可以直接使用 Promise API 来做同样的事情,就像第二个例子一样。

表现

现在,为了表演。让我们测试一下!

我刚刚写了这段代码 - f1() 给出 1 作为返回值, f2() 抛出 1 是一个异常:74d

 function f1() {
  return 1;
}

function f2() {
  throw 1;
}

现在让我们调用相同的代码百万次,首先是 f1()

 var sum = 0;
for (var i = 0; i < 1e6; i++) {
  try {
    sum += f1();
  } catch (e) {
    sum += e;
  }
}
console.log(sum);

然后让我们将 f1() 更改为 f2()

 var sum = 0;
for (var i = 0; i < 1e6; i++) {
  try {
    sum += f2();
  } catch (e) {
    sum += e;
  }
}
console.log(sum);

这是我为 f1 得到的结果:

 $ time node throw-test.js
1000000

real    0m0.073s
user    0m0.070s
sys     0m0.004s

这就是我得到的 f2

 $ time node throw-test.js
1000000

real    0m0.632s
user    0m0.629s
sys     0m0.004s

似乎您可以在一个单线程进程中每秒执行 200 万次抛出操作。如果你做的不止这些,那么你可能需要担心它。

概括

我不会担心 Node.js 中的类似事情。如果这样的东西被大量使用,那么它最终会被 V8 或 SpiderMonkey 或 Chakra 团队优化,每个人都会效仿——这并不是说它没有作为原则进行优化,只是没有问题。

即使它没有经过优化,我仍然会争辩说,如果你在 Node 中最大化你的 CPU,那么你可能应该用 C 编写你的数字运算——这就是本机插件的用途,等等。或者也许像 node.native 这样的东西会比 Node.js 更适合这项工作。

我想知道什么是需要抛出这么多异常的用例。通常抛出异常而不是返回值就是异常。

原文由 rsp 发布,翻译遵循 CC BY-SA 3.0 许可协议

类似于 Golang 中的错误处理的替代方案

因为 async/await 在底层使用了 promises,所以你可以像这样写一个小实用函数:

 export function catchEm(promise) {
  return promise.then(data => [null, data])
    .catch(err => [err]);
}

然后在你需要捕获一些错误时导入它,并包装你的异步函数,它返回一个承诺。

 import catchEm from 'utility';

async performAsyncWork() {
  const [err, data] = await catchEm(asyncFunction(arg1, arg2));
  if (err) {
    // handle errors
  } else {
    // use data
  }
}

原文由 Steve Banton 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题