一尘不染

在此之前和之后放置渔获物

node.js

我很难理解将.catchBEFORE和AFTER放在嵌套诺言之间的区别。

选择1:

test1Async(10).then((res) => {
  return test2Async(22)
    .then((res) => {
      return test3Async(100);
    }).catch((err) => {
      throw "ERROR AFTER THEN";
    });
}).then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});

选择2:

test1Async(10).then((res) => {
   return test2Async(22)
     .catch((err) => {
        throw "ERROR BEFORE THEN";
      })
      .then((res) => {
        return test3Async(100);
      });
  }).then((res) => {
    console.log(res);
  }).catch((err) => {
    console.log(err);
  });

每个函数的行为如下,如果号码是test1的失败<0,如果号码是test2的失败> 10,如果数量不TEST3失败100。在这种情况下,test2仅失败。

我试图运行并使test2Async失败,然后在执行之前和之后都以相同的方式运行,并且未执行test3Async。有人可以向我解释在不同地方放置渔获物的主要区别吗?

在每个函数中,我console.log('Running test X')都会检查它是否被执行。

出现此问题的原因是我发布的上一个线程如何将嵌套回调转换为Promise?。我认为这是一个不同的问题,值得发表另一个话题。


阅读 286

收藏
2020-07-07

共1个答案

一尘不染

因此,基本上,您是在问这两者之间有什么区别(哪里p是以前的代码创建的promise):

return p.then(...).catch(...);

return p.catch(...).then(...);

p解析或拒绝时存在差异,但是这些差异是否重要取决于.then().catch()处理程序中的代码做什么。

p解决时会发生什么:

在第一种方案中,当p解析时,将.then()调用处理程序。如果该.then()处理程序返回一个值或另一个最终解决的承诺,那么将.catch()跳过该处理程序。但是,如果.then()处理程序抛出或返回最终拒绝的promise,则.catch()处理程序将执行原始promise中的拒绝操作,同时执行处理程序p中发生的错误.then()

在第二种方案中,当p解析时,将.then()调用处理程序。如果该.then()处理程序抛出或返回最终拒绝的承诺,则该.catch()处理程序将无法捕获该承诺,因为它在链中之前。

因此,这是第一点。 如果.catch()处理程序是AFTER之后的,那么它也可以捕获.then()处理程序内部的错误。

p拒绝时会发生什么:

现在,在第一种方案中,如果Promise
p拒绝,则.then()跳过处理程序,并且.catch()将按您期望的方式调用处理程序。您在.catch()处理程序中执行的操作将确定返回的最终结果。如果您只是从.catch()处理程序中返回一个值或返回一个最终可解决的承诺,则由于您已“处理”错误并正常返回,因此承诺链将切换到已解决状态。如果您在.catch()处理程序中抛出或返回了被拒绝的诺言,则返回的诺言将保持被拒绝状态。

在第二种方案中,如果Promisep拒绝,则.catch()调用处理程序。如果您返回正常值或最终从.catch()处理程序中解决的承诺(从而“处理”错误),则承诺链将切换到已解决状态,并且将在调用.then()处理程序.catch()

这就是差异2。 如果.catch()处理程序在BEFORE之前,则它可以处理错误并允许.then()处理程序继续被调用。

何时使用:

如果只希望一个.catch()处理程序可以捕获原始诺言p或处理程序中的错误,.then()而拒绝来自p.then()处理程序应跳过该处理程序,则使用第一种方案。

如果您希望能够捕获原始promise中的错误,p并且可能(取决于条件),允许使用promise链继续解析,从而执行.then()处理程序,请使用第二种方案。

另一种选择

还有一个选项可以使用两个回调,您可以像下面这样传递.then()

 p.then(fn1, fn2)

这样可以保证仅会调用fn1fn2之一。如果p解决,fn1则将被调用。如果p拒绝,fn2则将被调用。结果的任何改变fn1都不会引起别人的注意,fn2反之亦然。因此,如果您想绝对确保无论处理程序本身发生了什么,都将仅调用两个处理程序之一,则可以使用p.then(fn1,fn2)

2020-07-07