Javascript 然后在之前和之后放置捕获物
我很难理解将Javascript 然后在之前和之后放置捕获物,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我很难理解将.catch放在嵌套承诺之前和之后的区别 备选案文1: test1Async(10).then((res) => { return test2Async(22) .then((res) => { return test3Async(100); }).catch((err) => { throw "ERROR AFTER THEN"; }); }).then((res) => { console.log(r
.catch
放在嵌套承诺之前和之后的区别
备选案文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);
});
每个函数的行为如下:如果数字为10
,则test1失败;如果数字不是100
,则test3失败。在这种情况下,test2只是失败了
我试着运行并使test2Async失败,之前和之后的行为都是相同的,这就是不执行test3Async。有人能给我解释一下在不同地方放置渔获物的主要区别吗
在每个函数中,Iconsole.log('Running test X')
,以检查它是否得到执行
这个问题的产生是因为我之前发布的帖子。我认为这是一个不同的问题,值得发布另一个主题。因此,基本上你是在问这两者之间有什么区别(其中
p
是从以前的一些代码创建的承诺):
及
p解析或拒绝时会有差异,但这些差异是否重要取决于.then()
或.catch()处理程序中的代码执行什么操作
当p
解析时会发生什么情况:
在第一个方案中,当p
解析时,调用.then()
处理程序。如果该.then()
处理程序返回一个值或另一个最终解析的承诺,则跳过.catch()
处理程序。但是,如果.then()
处理程序抛出或返回最终拒绝的承诺,则.catch()
处理程序将执行原始承诺p
中的拒绝,以及.then()
处理程序中发生的错误
在第二个方案中,当p
解析时,调用.then()
处理程序。如果该.then()
处理程序抛出或返回最终拒绝的承诺,则.catch()
处理程序无法捕获该承诺,因为它位于链中的前面
所以,这就是区别1。如果.catch()
处理程序在之后,则它还可以捕获.then()
处理程序中的错误。
当p
拒绝时会发生什么情况:
现在,在第一个方案中,如果promisep
拒绝,则跳过.then()
处理程序,并按预期调用.catch()
处理程序。在.catch()
处理程序中执行的操作决定了返回的最终结果。如果您只是从.catch()
处理程序返回一个值,或者返回最终解析的承诺,那么承诺链将切换到已解析状态,因为您“处理”了错误并正常返回。如果在.catch()
处理程序中抛出或返回被拒绝的承诺,则返回的承诺将保持被拒绝状态
在第二个方案中,如果promisep
拒绝,则调用.catch()
处理程序。如果您返回一个正常值或一个最终从.catch()
处理程序解析的承诺(从而“处理”错误),则承诺链将切换到已解析状态,并将调用.catch()
后的.then()
处理程序
这就是区别2。如果.catch()
处理程序在前面,则它可以处理错误并允许调用.then()
处理程序。
在什么时候使用它:
如果只需要一个.catch()
处理程序,可以捕获原始承诺p
或中的错误,请使用第一个方案。然后()
处理程序和p
的拒绝应该跳过。然后()
处理程序
如果您希望能够捕获原始承诺p
中的错误,并且可能(根据条件)允许承诺链继续解析,从而执行.then()
处理程序,请使用第二种方案
另一种选择
还有一个选项可以使用两个回调,您可以将它们传递到。然后()
,如中所示:
p.then(fn1, fn2)
这保证只调用fn1
或fn2
中的一个。如果p
解析,则将调用fn1
。如果p
拒绝,则将调用fn2
。fn1
结果的任何变化都不能使fn2
被调用,反之亦然。因此,如果您想绝对确保只调用两个处理程序中的一个,而不管处理程序本身发生了什么,那么您可以使用p。然后(fn1,fn2)
非常好,但我认为添加类似的同步代码是个好主意
return p.then(...).catch(...);
与同步模式类似:
try {
iMightThrow() // like `p`
then()
} catch (err) {
handleCatch()
}
如果iMightThrow()。如果它确实抛出(或者如果then()
本身抛出),则将调用handleCatch()
。请注意,catch
块无法控制是否调用then
另一方面,
return p.catch(...).then(...);
与同步模式类似:
try {
iMightThrow()
} catch (err) {
handleCatch()
}
then()
在这种情况下,如果iMightThrow()
没有抛出,则将执行then()
。如果它确实抛出,那么将由handleCatch()
决定是否调用then()
,因为如果handleCatch()
rethrows,那么将不会调用then()
,因为异常将立即抛出给调用方。如果handleCatch()
可以优雅地处理问题,那么将调用then()
。两者都可以。then和.catch可以更改承诺。。。所以我不确定这种误解是从哪里来的。如果您将catch放在.then之前,它将捕获在.then和.then之前发生的拒绝,并将根据.catch中发生的情况运行it's done/fail回调,反之亦然,当您交换它们时。Sorr
return p.catch(...).then(...);
try {
iMightThrow()
} catch (err) {
handleCatch()
}
then()