我想知道是否有人知道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));

如果运行,您将获得:
first catch: foo
second catch: foo

据我所知,每次调用Promise.prototype.then时,都会创建并返回一个新的Promise。我能想到的能够为每个链找到下一个错误处理程序的唯一方法是拥有对子代的引用数组。因此,如果Promise被拒绝,它将遍历所有子项,并在每个子链中找到最接近的拒绝处理程序。

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

最佳答案

我的看法:
将promise视为嵌套数组:[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
现在想象我们开始执行,它从最顶层的数组开始。我们为每个数组都有一个索引,用于指定在执行方面要等待的元素。
我们首先调用.then1,它本身返回一个promise链(另一个数组)。当发生错误时,您的层次结构数组中最低的数组(最深的数组)会跳过(不执行)(它是元素),直到找到catch为止。如果是这样,它将执行catch并继续执行其他元素。如果找不到catch,它将要求父数组找到并执行catch,跳过所有元素(包括其子数组),因为它们没有捕获
在我们的示例中,如果then1.2中发生错误,它将被catch1.1捕获,但是如果它发生于then1.3中,则将跳过catch1then1.4一直传播到then2中。
编辑:
这是要试验的代码:
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))
它记录:

09-20 23:25