【问题标题】:Node.js async/await try catch flow - best practiceNode.js async/await try catch flow - 最佳实践
【发布时间】:2018-05-29 15:05:07
【问题描述】:

我最近从promises 搬到了async/await。但是,我不确定try...catch 正确的流程。我有以下示例:

const rp = require('request-promise');

const func2 = async () => {
    const response1 = await rp('http://nodejs.org/dist/index.json');
    if (response1) {
      return await rp('http://headers.jsontest.com'); // #opt 1: return a value
      // return rp('http://headers.jsontest.com'); // #opt 2: return a promise:
    }
}

(func1 = async () => {
  try {
    const response = await func2();
    console.log('Success!');
  } catch(e) {
    console.log('Failed!');
  }
})();

我想知道是否应该将try...catch 添加到func2,但我得出的结论是它已经在func1try...catch 中处理。

此代码有效吗?

【问题讨论】:

  • 是的,它是有效的,但这是一个高度自以为是和上下文相关的问题。这还取决于您希望在func2 看到哪些异常以及您希望如何对它们做出反应。例如,您可能希望立即处理 func2 中的异常,以便您可以重试/恢复并仍然向调用者返回有效响应。
  • 你能遇到response1是“假”但没有抛出错误的情况吗?因为在那种情况下response 将是undefined - 这有效吗?

标签: javascript node.js asynchronous async-await ecmascript-2017


【解决方案1】:

此代码有效吗?

是的。 (关于try/catch 方面,请参阅下面的“旁注”。)

我想知道是否应该将try...catch 添加到func2,但我得出结论它已经在func1try...catch 中处理。

是的,是的。就像使用非async 函数一样,如果您想在那里处理错误(全部或部分然后(重新)抛出),则只需要func2 中的try/catch。如果你不这样做,让它传播给调用者。只要确保它在某处被处理。


旁注:我假设您的func2 有一个return,而response1 是一个假值。如果不是,func2 的 promise 的分辨率值将是 undefined


旁注 2:我猜您在此处添加了 func1 = 部分只是为了给自己一个名称以供在问题中引用,而它不在您的真实代码中。但万一是这样:除非您在未显示的地方声明了它,否则在您的示例中 func1 是一个隐式全局。建议避免这些。 :-) 更多内容见我的博文:The Horror of Implicit Globals


旁注 3 (他确实有点,不是吗?):如果你没有在其他任何地方使用 func1(只是为了方便 @987654340 使用它作为包装器@use inside),如果你愿意,你可以通过使用async 函数返回承诺的事实来避免一定程度的缩进:

(async () => {
  const response = await func2();
  console.log('Success!');
})().catch(e => {
  console.log('Failed!');
});

好处是它更简洁一些。缺点是它混合了隐喻。 :-) 那和 try/catch完全相同的事情,这完全取决于您喜欢如何编写它,这完全取决于您。

【讨论】:

  • @LukeStoward:我刚刚删除了那个括号,它没有添加任何东西。 (在 general 的情况下,我不同意你的观点,但无论如何,意见方面都不需要进入答案,所以...... :-))
  • 我很感激,我想这是你是否喜欢快速失败和大声失败的问题。 :)
  • @LukeStoward:无论哪种方式,你都在快速而响亮地失败。
  • @iT.J.Crowder for the "side note" 如果解析站点 url 将失败,它将捕获,否则它将获得一些价值。我看不出什么时候是undefined。附言这个例子只是为了举例。
  • @wizard:如果您的函数的第一行将抛出(拒绝)或返回一个真实值,那么根本不需要if。抛出(被拒绝的承诺)将在 if 之前退出 func2
猜你喜欢
  • 2013-12-28
  • 2017-01-31
  • 1970-01-01
  • 2019-03-14
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2013-09-06
相关资源
最近更新 更多