故障
译者注:这段如果有配套代码会更容易理解,但是没有,所以凑合看吧。
常规的 JavaScript 计算可能会因抛出异常而失败。 异步计算经常需要类似的东西。 网络请求可能会失败,或者作为异步计算的一部分的某些代码,可能会引发异常。
异步编程的回调风格中最紧迫的问题之一是,确保将故障正确地报告给回调函数,是非常困难的。
一个广泛使用的约定是,回调函数的第一个参数用于指示操作失败,第二个参数包含操作成功时生成的值。 这种回调函数必须始终检查它们是否收到异常,并确保它们引起的任何问题,包括它们调用的函数所抛出的异常,都会被捕获并提供给正确的函数。
Promise
使这更容易。可以解决它们(操作成功完成)或拒绝(故障)。只有在操作成功时,才会调用解析处理器(使用then
注册),并且拒绝会自动传播给由then
返回的新Promise
。当一个处理器抛出一个异常时,这会自动使then
调用产生的Promise
被拒绝。因此,如果异步操作链中的任何元素失败,则整个链的结果被标记为拒绝,并且不会调用失败位置之后的任何常规处理器。
就像Promise
的解析提供了一个值,拒绝它也提供了一个值,通常称为拒绝的原因。当处理器中的异常导致拒绝时,异常值将用作原因。同样,当处理器返回被拒绝的Promise
时,拒绝流入下一个Promise
。Promise.reject
函数会创建一个新的,立即被拒绝的Promise
。
为了明确地处理这种拒绝,Promise
有一个catch
方法,用于注册一个处理器,当Promise
被拒绝时被调用,类似于处理器处理正常解析的方式。 这也非常类似于then
,因为它返回一个新的Promise
,如果它正常解析,它将解析原始Promise
的值,否则返回catch
处理器的结果。 如果catch
处理器抛出一个错误,新的Promise
也被拒绝。
作为简写,then
还接受拒绝处理器作为第二个参数,因此你可以在单个方法调用中,装配这两种的处理器。
传递给Promise
构造器的函数接收第二个参数,并与解析函数一起使用,它可以用来拒绝新的Promise
。
通过调用then
和catch
创建的Promise
值的链条,可以看作异步值或失败沿着它移动的流水线。 由于这种链条通过注册处理器来创建,因此每个链条都有一个成功处理器或与其关联的拒绝处理器(或两者都有)。 不匹配结果类型(成功或失败)的处理器将被忽略。 但是那些匹配的对象被调用,并且它们的结果决定了下一次会出现什么样的值 — 返回非Promise
值时成功,当它抛出异常时拒绝,并且当它返回其中一个时是Promise
的结果。
就像环境处理未捕获的异常一样,JavaScript 环境可以检测未处理Promise
拒绝的时候,并将其报告为错误。