promise链如何引用下一个错误处理程序

Ale*_*lls 11 javascript node.js ecmascript-6 es6-promise

我想知道是否有人知道promise链如何引用下一个错误处理程序 - 例如:

  const p = new Promise(resolve => resolve(5))
   .then(v => 5*v)
   .then(v => { throw 'foo' });

  p.then(v => v/4)
   .then(v => v+3)
   .catch(e => console.error('first catch:', e));

  p.then(v => v/4)
   .then(v => v+3)
   .catch(e => console.error('second catch:', e));
Run Code Online (Sandbox Code Playgroud)

如果你跑了,你会得到:

first catch: foo
second catch: foo
Run Code Online (Sandbox Code Playgroud)

据我所知,每次都Promise.prototype.then被召唤,创造并返回新的承诺.我能想到能够为每个链找到下一个错误处理程序的承诺的唯一方法是拥有一个对子项的引用数组.因此,如果承诺被拒绝,它将通过所有孩子并在每个子链中找到最接近的拒绝处理程序.

有谁知道这是如何实现的?

Ale*_*nov 8

我看待它的方式:

将promises视为嵌套数组:

[then1,[then1.1, then1.2, catch1.1, then1.3, then1.4], then2, catch1]

看起来像这样:

new Promise(...)
.then(() => {         // <- 1
  return Promise(...)
          .then()     // <- 1.1
          .then()     // <- 1.2
          .catch()    // <- 1.1
          .then()     // <- 1.3
          .then()     // <- 1.4
})
.then()               // <- 2
.catch()              // <- 1
Run Code Online (Sandbox Code Playgroud)

现在假设我们开始执行,它从最顶层的数组开始.我们为每个数组都有一个索引,指定我们在执行方面正在等待哪个元素.我们从调用开始.then1,它本身返回一个promise链(另一个数组).当发生错误时,层次结构中最低的数组(最深的一个)跳过(不执行)它的元素,直到找到它为止catch.如果是,则执行catch并继续执行其他元素.如果它没有找到catch它要求父数组找到并执行a catch,则跳过所有元素,包括它的子数组,因为它们没有捕获.

在我们的示例中,如果发生错误,then1.2它将被捕获catch1.1,但如果它发生在then1.3它将一直传播到catch1跳过then1.4then2

编辑:

以下是要试验的代码:

new Promise(res => res())
.then(() => 
    new Promise(res => res())
    .then(() => console.log(1))
    .then(() => {console.log(2); throw "Error 1"})
    .catch((err) => console.log(err))
    .then(() => {console.log(3); throw "Error 2"}))
    .then(() => console.log(4))
.then(() => 
    new Promise(res => res())
    .then(() => console.log(6))
    .then(() => {console.log(7); throw "Error 3"})
    .catch((err) => console.log(err))
    .then(() => console.log(8))
    .then(() => {console.log(9); throw "Error 4"}))
.then(() => console.log(10))
.catch((err) => console.log(err))
Run Code Online (Sandbox Code Playgroud)

它记录:

1

2

错误1

3

错误2