首页 文章

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

提问于
浏览
4

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

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

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

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

1 回答

  • 8

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

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

    • then 是一种功能相当的方法 . 它的回调只应该接收一个数据参数,即promise的结果值 .

    • 将其他 resolve / reject 函数传递给回调函数不适用于多个参数甚至可变参数函数 .

    • then 通常用作普通映射函数 . 你只需 return 新值,不需要 resolve .

    • 当你真的想在你的回调中做一些你可以使用 resolve / reject 的异步时,你最好还是应该使用一个承诺 - 你可以随后返回 .

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

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

    它们并不真正意味着用于控制流(如分支,循环等),而是用于异常处理: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? .

相关问题