异步函数的 neverthrow 有何意义?

bad*_*872 8 error-handling try-catch typescript

在我最初在整个 typescript/node 应用程序中使用 throw 和 catch 后,我偶然发现了 neverthrow(https://www.npmjs.com/package/neverthrow)。

我写了第一个更大的应用程序和打字稿,才意识到缺少将函数标记为抛出的能力实际上是一个多么大的问题。

neverthrow 或其他基于任一解决方案似乎都很好。对于我的非异步函数,我已经将所有内容更改为永不抛出。

我真的不明白为什么我应该费心包装所有异步函数以返回 ResultAsync 。任何异步函数都被标记为可能本质上抛出错误(因为它们返回 Promise),还是我错了?我是否遗漏了任何一点,我确实应该更改所有异步函数以使用 ResultAsync?

Joo*_*nas 7

ResultAsync<T, E>使用类型之类的东西代替 .没有什么好处Promise<T>

从类型本身可以看出,前一个选项有一个E泛型参数,指示结果可能包含的错误类型。这是非常有益的,因为您可以独立处理每种错误类型,而不是捕获通用错误实例。以HTMLImageElement.decode为例;它返回一个可能会抛出异常的承诺EncodingError,但如果不检查文档你就不会知道这一点。

另一个好处来自被迫处理潜在的错误结果。JavaScript 错误是未经检查的,这意味着没有编译器或解释器来确保您始终包装await promise在 try-catch 中。另一方面,当您 时await result,您必须检查它是产生结果 ( result.isOk() === true) 还是抛出错误 ( result.isErr() === true)。这意味着每次您想要打开(获取TResult<T, _>结果时,您必须处理潜在的错误情况。理论上,这会产生更健壮且故障安全的代码。

但结果并非没有缺点。Javascript 生态系统已采用 Promises 作为异步返回内容的标准方式,因此ResultAsync可能无法在所有地方都工作Promise。此外,每次想要解开结果时都必须处理潜在的错误结果,这会使代码变得更加冗长。

如果您主要处理在同一项目中编写的异步代码,并且认为您可以从更多的故障安全代码中受益,那么在ResultAsync您要使用的任何地方使用Promise.