在之前和之后放置捕获物

我很难理解把.catch(function(err)BEFORE和AFTER then在嵌套promise中的区别。

test1Async(10).then(function (lol) { return test2Async(22) .then(function (lol) { return test3Async(100); }).catch(function (err) { throw "ERROR AFTER THEN"; }); }).then(function (results) { console.log(results); }).catch(function (err) { console.log(err); }); 

和这个

 test1Async(10).then(function (lol) { return test2Async(22) .catch(function (err) { throw "ERROR BEFORE THEN"; }) .then(function (lol) { return test3Async(100); }); }).then(function (results) { console.log(results); }).catch(function (err) { console.log(err); }); 

每个函数的行为如下,如果number <0 ,则test1失败,如果number > 10 ,则test2失败;如果number不是100 ,则test3失败。 在这种情况下,test2只是失败。

我试图运行,并使test2Async失败,BEFORE和AFTER,然后行为相同的方式,而不是执行test3Async。 有人可以向我解释在不同的地方摆放渔获物的主要区别吗?

在每个函数我console.log(运行testingX),以检查是否得到执行。

这个问题出现是因为我之前的线程发布如何将嵌套的callback变成诺言? 。 我认为这是一个不同的问题,值得发表另一个话题。

所以,基本上你问这两者之间有什么区别(其中p是从以前的代码中创build的一个承诺):

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

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

当pparsing或拒绝时,有差异,但是这些差异是否重要取决于.catch().catch()处理程序中的代码是做什么的。

pparsing时会发生什么:

在第一个scheme中,当pparsing时,调用.then()处理程序。 如果.then()处理程序返回一个值或另一个最终解决的promise,则跳过.catch()处理程序。 但是,如果.then()处理程序抛出或返回一个最终拒绝的promise,那么.catch()处理程序将执行原始promise中的拒绝,而且.then()处理程序。

在第二个scheme中,当pparsing时,调用.then()处理程序。 如果.then()处理程序抛出或返回最终拒绝的承诺,那么.catch()处理程序无法捕获,因为它在链中。

所以,这是差异#1。 如果.catch()处理程序是AFTER,那么它也可以捕获.catch()处理程序中的错误。

当拒绝时会发生什么:

现在,在第一个scheme中,如果promise拒绝,那么.catch()处理程序将被跳过, .catch()处理程序将按照您的预期调用。 你在.catch()处理程序中所做的决定了最终结果返回的内容。 如果您只是从.catch()处理程序返回值或返回最终解决的承诺,那么承诺链将切换到已解决的状态,因为您“处理”了错误并正常返回。 如果您在.catch()处理程序中抛出或返回被拒绝的承诺,则返回的承诺将保持拒绝状态。

在第二种scheme中,如果承诺p拒绝,则.catch()处理程序。 如果你返回一个普通的值或者一个最终从.catch()处理程序parsing出来的.catch()从而“处理”错误),那么promise链在.catch()之后切换到parsing状态和.catch()将被调用。

所以这是差异#2。 如果.catch()处理程序是BEFORE,那么它可以处理该错误并允许.then()处理程序仍然被调用。

何时使用哪个:

如果只需要一个.catch()处理程序,可以捕获原始的promise p.catch()处理程序中的错误,并且来自p的拒绝应该跳过.catch()处理程序,请使用第一个scheme。

使用第二个scheme,如果你想能够捕获原始的承诺p中的错误,也许(取决于条件),允许承诺链继续解决,从而执行.then()处理程序。

另一种select

还有一个选项可以使用这两个callback,你可以传递给.then()如下所示:

  p.then(fn1, fn2) 

这保证了fn1fn2中只有一个被调用。 如果pparsing,那么fn1将被调用。 如果p拒绝,那么fn2将被调用。 fn1的结果没有任何变化可以使得fn2被调用,反之亦然。 所以,如果你想确保只有你的两个处理程序中的一个被调用,而不pipe在处理程序本身中发生了什么,那么你可以使用p.then(fn1, fn2)

jfriend00的答案非常好,但是我认为添加类似的同步代码是个好主意。

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

类似于同步:

 try { iMightThrow() // like `p` then() } catch (err) { handleCatch() } 

如果iMightThrow()不抛出, then()将被调用。 如果它抛出(或如果then()本身抛出),然后handleCatch()将被调用。 请注意catch块是否无法控制是否被调用。

另一方面,

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

类似于同步:

 try { iMightThrow() } catch (err) { handleCatch() } then() 

在这种情况下,如果iMightThrow()不抛出,那么将执行then() 。 如果抛出, handleCatch()决定是否调用了then() ,因为如果handleCatch()抛出,则不会调用then() ,因为exception将立即抛出给调用者。 如果handleCatch()可以优雅地处理这个问题, then()将被调用。