我在我的项目中使用 @typescript-eslint/no-floating-promises
规则。如果我写这样的代码,这条规则就会抱怨 -
functionReturningPromise() .then(retVal => doSomething(retVal));
它希望我为此 Promise
添加一个 catch
块。如果我想在异常处理块中添加一些逻辑,这对我来说是有意义的。但是,在很多情况下我不需要它。我对抛出的错误很满意。因此,为了抑制此规则引发的错误,我最终这样做了 -
functionReturningPromise() .then((retVal) => doSomething(retVal)) .catch((error) => { throw error; });即使我没有像上面那样添加
catch
块,error
仍然会以相同的方式抛出(至少在我的控制台输出中看到它)。因此,我不明白显式指定此 catch
块的意义。我错过了什么吗?如果我添加/不添加 catch
块,抛出 error
的方式真的有区别吗?
评论者都很好地回答了您的问题 - 但为了通过示例说明为什么这很重要,请想象以下代码:
这段代码看起来相当无害 - 有一个未处理的无操作承诺拒绝,启动后 1 秒程序将记录
'hello'
。在浏览器中 - 这正是将会发生的情况 - 浏览器将记录“未捕获的承诺拒绝”错误,但否则会忽略它。
然而,在 NodeJS(从 Node v15 开始)中,未处理的 Promise 拒绝是一个硬错误 - 这意味着进程在检测到错误时将退出!
您可以通过在终端中运行代码来验证这一点(
-e
的意思是“评估并运行此代码字符串”)您可以看到
'hello'
永远不会被打印,因为进程在 1 秒之前终止!要验证事情是否按预期工作,您可以将
.reject
更改为.resolve
:因此,如果您正在使用任何 LTS 支持的版本编写 NodeJS 应用程序,那么您绝对应该处理错误,否则您将面临意外崩溃的风险。
如果您的代码仅在浏览器中运行,那么您可能想知道是否应该处理失败 - 毕竟您的用户没有查看控制台,因此他们不会知道发生了任何不好的事情,所以谁在乎呢?从“仅代码”的角度来看,您是正确的 - 但是,当出现问题时,您的用户希望从他们的应用程序中获得反馈。
想象一下以下场景 - 您的 Promise 跟踪 API 调用的结果,该调用提交用户在您的应用程序中输入的一些数据。如果该 API 调用由于某种原因失败,那么您的应用程序应该做出适当的响应并告诉用户出了问题。
处理它的替代方法可能意味着您的应用程序显示无限加载旋转器,或者用户认为他们的数据已成功提交,但实际上并未成功。无论哪种方式 - 这是一个非常糟糕且破碎的用户体验!
最后做一些像
.catch(e => { throw e })
这样的事情,你实际上并没有处理错误。当然,这段代码会使 linter 保持沉默 - 但您所做的只是创建一个新的、被拒绝的承诺,该承诺将记录到控制台。相反,您应该以某种方式将错误连接到应用程序的 UI,例如像.catch(e => {alert(e); throw e })
这样简单的东西会更好。