为什么在JS中使用异常来拒绝承诺?

时间:2014-02-06 23:38:32

标签: javascript promise

我所指的规范是http://promises-aplus.github.io/promises-spec/

使用then()时,您可以返回一个承诺,并在您希望时拒绝承诺,或者您可以抛出异常拒绝承诺。

为什么api不是以then函数的方式设计的,它传递的解析和拒绝函数就像原始的promise构造函数一样?

许多语言中的异常都很繁多(我也假设在javascript中)所以看起来他们使用它们作为流控制的选择似乎很奇怪。创建一个全新的promise对象并返回它,只是为了拒绝它,增加了代码膨胀IMO。如果抛出异常(例如语法错误,或者在未定义的对象上调用函数等),调试也会变得更加困难。

1 个答案:

答案 0 :(得分:8)

  

为什么api不是以这样的方式设计的呢?对于then函数,它会像原始的promise构造函数一样传递一个解析和拒绝函数?

实际上,该规范中的API在各种实现中成为共识。但是,可能导致这一点的一些观点是:

  • then是一种功能相当的方法。它的回调只应该接收一个数据参数,即promise的结果值。
  • 将其他resolve / reject函数传递给回调函数不适用于多个参数甚至可变函数。
  • then通常用作普通映射函数。您只需return新值,不需要resolve
  • 如果你真的想在你的回调中做一些异步的事情,你可以使用resolve / reject,你最好还是应该使用一个承诺 - 你可以随时返回。

我曾经使用可选的resolve / reject参数实现了一个Promise lib,但使用它很繁琐 - 而且由于#4我很少需要它们。使用它们容易出错,你可能很容易忘记某些事情(比如处理错误或进度事件) - 就像那些手动构建和返回从promise回调中解决的延迟而不是调用then的人一样。 / p>

  

异常很重,所以看起来很奇怪他们将它们用作流量控制的选择。

它们实际上不是用于控制流(如分支,循环等),而是用于异常处理rejections are exceptional。大多数Promise开发人员都希望将它们作为同步(阻塞)代码的替代方案来实现 - 其中IO总是抛出异常,因此他们对此进行了调整。拒绝仍然被解释为异步等同于try … catch,尽管它们的monadic性质可以用于更强大的方式和更高级别的应用程序。

  

创建一个全新的promise对象并返回它,只是为了拒绝它,增加了代码膨胀IMO。

return new RejectedPromise(…)return reject(…)throw Error(…)之间没有太大区别。

  

如果抛出异常(例如语法错误,或者在未定义的对象上调用函数等),调试也会变得更加困难。

大多数Promise开发人员似乎将此视为优势实际上 - (意外)异常即使在异步代码中也会被自动捕获,因此可以处理它们而不是炸毁程序(不被注意)。另请参阅exception handling, thrown errors, within promisesacceptable promise pattern for 'LOUD' errors?