`<..>.get().then().then().catch().finally()` 和 `<...>.get().then().catch( ).then().finally`

What is the difference between doing `<..>.get().then().then().catch().finally()` vs `<...>.get().then().catch().then().finally`

我正在学习 Javascript 中的 promises 并且想知道按以下方式重新排序时是否有任何区别 <...>.get().then().then().catch().finally()<...>.get().then().catch().then().finally()?

有以下链

<...>.get().then().then().catch().finally()

catch 方法将处理链中所有先前承诺的拒绝,而对于以下链

<...>.get().then().catch().then().finally()

catch 方法将不会处理最后一个 then 方法返回的拒绝承诺。

当您想要处理承诺拒绝并将其转化为实现由 catch 方法返回的承诺以允许承诺链继续时,这种链很有用。

如果第二个链的结果承诺在某处使用,或者如果您从如下所示的函数返回此链末尾的承诺,

function foo() {
  return <...>.get().then().then().catch().finally();
}

然后不使用另一个 catch 方法就可以了,因为在这种情况下,调用此函数的代码可以处理承诺链本身未捕获和处理的承诺拒绝。

但是,如果不是这种情况,那么在最后一个 then 方法调用之后,您绝对应该有第二个 catch 方法。

是的,它们是不同的。

假设你有这个:

<...>.get().then(() => A()).then(() => B()).catch(() => ErrorHandling()).finally(() => D())

<...>.then(() => A()).catch(() => ErrorHandling()).then(() => B()).finally(() => D())

您可以将其转换为 await/async 表示:

// <...>.get().then(() => A()).then(() => B()).catch(() => ErrorHandling()).finally(() => D())

try {
  await get();
  await A();
  await B();
} catch( ) {
  await ErrorHandling()
} finally {
  await D();
}

// <...>.then(() => A()).catch(() => ErrorHandling()).then(() => B()).finally(() => D())

try {
  try {
    await get();
    await A();
  } catch( ) {
    await ErrorHandling()
  }
  await B();
} finally {
  await D();
}

在第一种情况下,如果 getA 导致错误,则不会执行 B。在第二种情况下,即使 getA 导致错误,B 也会执行,唯一不会执行的情况是 ErrorHandling 导致错误错误。

所以使用第一个如果B依赖getA才能成功执行。使用第二种情况,例如如果 B 应该做一些事情 getA 是否成功无关紧要。