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

IT技术 javascript promise
2021-02-13 03:18:03

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

使用时then(),您可以返回一个promise,并在需要时拒绝该promise,或者您可以抛出异常来拒绝一个promise。

为什么 api 没有以这种方式设计,对于then函数,它像原始的 promise 构造函数一样传递了一个 resolve 和 reject 函数?

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

1个回答

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

实际上,该规范中的 API 是各种实现之间的共识。但是,可能导致这种情况的一些要点是:

  • then是一种相当实用的方法。它的回调只应该接收一个数据参数,即Promise的结果值。
  • 将额外的resolve/reject函数传递给回调函数不适用于多个参数甚至可变参数函数。
  • then通常用作普通映射函数。你只是return新值,resolve不需要。
  • 当你真的想在你的回调中做一些异步的事情,你可以使用resolve/ reject,你最好无论如何都应该使用一个promise - 然后你可以简单地返回它。

我曾经用可选的resolve/reject参数实现了一个 Promise 库,但使用起来很乏味——而且我很少需要它们,因为 #4。使用它们很容易出错,你很容易忘记一些东西(比如处理错误或进度事件)——就像那些手动构建和返回由 Promise 回调解决的延迟而不是调用then.

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

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

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

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

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

大多数 Promise 开发人员似乎认为这实际上是一个优势- 即使在异步代码中的(意外)异常也会被自动捕获,因此它们可以被处理而不是炸毁程序(未被注意到)。另请参阅异常处理、抛出的错误、在Promise内以及“大声”错误的可接受Promise模式?.