故障

译者注:这段如果有配套代码会更容易理解,但是没有,所以凑合看吧。

常规的 JavaScript 计算可能会因抛出异常而失败。 异步计算经常需要类似的东西。 网络请求可能会失败,或者作为异步计算的一部分的某些代码,可能会引发异常。

异步编程的回调风格中最紧迫的问题之一是,确保将故障正确地报告给回调函数,是非常困难的。

一个广泛使用的约定是,回调函数的第一个参数用于指示操作失败,第二个参数包含操作成功时生成的值。 这种回调函数必须始终检查它们是否收到异常,并确保它们引起的任何问题,包括它们调用的函数所抛出的异常,都会被捕获并提供给正确的函数。

Promise使这更容易。可以解决它们(操作成功完成)或拒绝(故障)。只有在操作成功时,才会调用解析处理器(使用then注册),并且拒绝会自动传播给由then返回的新Promise。当一个处理器抛出一个异常时,这会自动使then调用产生的Promise被拒绝。因此,如果异步操作链中的任何元素失败,则整个链的结果被标记为拒绝,并且不会调用失败位置之后的任何常规处理器。

就像Promise的解析提供了一个值,拒绝它也提供了一个值,通常称为拒绝的原因。当处理器中的异常导致拒绝时,异常值将用作原因。同样,当处理器返回被拒绝的Promise时,拒绝流入下一个PromisePromise.reject函数会创建一个新的,立即被拒绝的Promise

为了明确地处理这种拒绝,Promise有一个catch方法,用于注册一个处理器,当Promise被拒绝时被调用,类似于处理器处理正常解析的方式。 这也非常类似于then,因为它返回一个新的Promise,如果它正常解析,它将解析原始Promise的值,否则返回catch处理器的结果。 如果catch处理器抛出一个错误,新的Promise也被拒绝。

作为简写,then还接受拒绝处理器作为第二个参数,因此你可以在单个方法调用中,装配这两种的处理器。

传递给Promise构造器的函数接收第二个参数,并与解析函数一起使用,它可以用来拒绝新的Promise

通过调用thencatch创建的Promise值的链条,可以看作异步值或失败沿着它移动的流水线。 由于这种链条通过注册处理器来创建,因此每个链条都有一个成功处理器或与其关联的拒绝处理器(或两者都有)。 不匹配结果类型(成功或失败)的处理器将被忽略。 但是那些匹配的对象被调用,并且它们的结果决定了下一次会出现什么样的值 — 返回非Promise值时成功,当它抛出异常时拒绝,并且当它返回其中一个时是Promise的结果。

就像环境处理未捕获的异常一样,JavaScript 环境可以检测未处理Promise拒绝的时候,并将其报告为错误。