Zan*_*nko 81 javascript node.js promise bluebird
我无法理解将.catchBEFORE和AFTER放在嵌套的promise中之间的区别.
备选方案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);
});
Run Code Online (Sandbox Code Playgroud)
备选方案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);
});
Run Code Online (Sandbox Code Playgroud)
每个函数的行为如下,如果number为<0test2则test1失败,如果number为,则test1失败,如果number为number则> 10test3失败100.在这种情况下,test2只是失败了.
我尝试运行并使test2Async失败,BEFORE和AFTER之后的行为方式相同,并且没有执行test3Async.有人可以向我解释将捕捞放在不同地方的主要区别吗?
在每个函数中我console.log('Running test X')都要检查它是否被执行.
这个问题出现是因为我发布的上一个帖子如何将嵌套回调转换为promise?.我认为这是一个不同的问题,值得发布另一个主题.
jfr*_*d00 186
所以,基本上你要问的是这两者之间有什么区别(哪里p是从以前的代码创建的一个承诺):
return p.then(...).catch(...);
Run Code Online (Sandbox Code Playgroud)
和
return p.catch(...).then(...);
Run Code Online (Sandbox Code Playgroud)
有差异要么当p解决或拒绝,但这些差异是否重要与否取决于什么内部的代码.then()或.catch()处理程序一样.
p结算时会发生什么:在第一个方案中,当p解析时,.then()调用处理程序.如果该.then()处理程序返回一个值或最终解析的另一个promise,.catch()则跳过该处理程序.但是,如果.then()处理程序抛出或返回最终拒绝的promise,则.catch()处理程序将对原始promise中的拒绝执行p,但也会在处理程序中执行错误.then().
在第二种方案中,当p解析时,.then()调用处理程序.如果该.then()处理程序抛出或返回最终拒绝的promise,则.catch()处理程序无法捕获它,因为它位于链中.
所以,这就是#1的差异.如果.catch()处理程序是AFTER,那么它也可以捕获.then()处理程序内的错误.
p拒绝后会发生什么:现在,在第一个方案中,如果promise p拒绝,则.then()跳过.catch()处理程序,并按照您的预期调用处理程序.您在.catch()处理程序中执行的操作将确定返回的内容作为最终结果.如果您只是从.catch()处理程序返回一个值或返回最终解析的promise,那么promise链会切换到已解析状态,因为您"处理"了错误并正常返回.如果您在.catch()处理程序中抛出或返回被拒绝的承诺,则返回的承诺将被拒绝.
在第二种方案中,如果promise p拒绝,则.catch()调用处理程序.如果返回正常值或最终从.catch()处理程序解析的promise (因此"处理"错误),则promise链将切换到已解析状态,并在调用.then()之后处理程序.catch().
这就是#2的差异.如果.catch()处理程序是BEFORE,那么它可以处理错误并允许.then()处理程序仍然被调用.
如果您只想要一个.catch()可以捕获原始承诺p或处理程序中的错误的.then()处理程序,并且拒绝来自p跳过.then()处理程序,请使用第一个方案.
如果您希望能够捕获原始承诺中的错误p并且可能(取决于条件),请使用第二种方案,允许promise链继续解析,从而执行.then()处理程序.
还有一个选项可以使用您可以传递给的两个回调,.then()如:
p.then(fn1, fn2)
Run Code Online (Sandbox Code Playgroud)
这保证了只有一个fn1或fn2将要被调用.如果p解决,那么fn1将被调用.如果p拒绝,那么fn2将被调用.没有变化的结果fn1可以fn2被召唤,反之亦然.因此,如果您想要确保只调用两个处理程序中的一个,而不管处理程序本身发生了什么,那么您可以使用p.then(fn1, fn2).
aki*_*don 20
jfriend00的答案非常好,但我认为添加类似的同步代码是个好主意.
return p.then(...).catch(...);
Run Code Online (Sandbox Code Playgroud)
类似于同步:
try {
iMightThrow() // like `p`
then()
} catch (err) {
handleCatch()
}
Run Code Online (Sandbox Code Playgroud)
如果iMightThrow()不扔,then()将被调用.如果它确实抛出(或者如果then()它自己抛出),那么handleCatch()将被调用.注意catch块如何无法控制是否then被调用.
另一方面,
return p.catch(...).then(...);
Run Code Online (Sandbox Code Playgroud)
类似于同步:
try {
iMightThrow()
} catch (err) {
handleCatch()
}
then()
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果iMightThrow()不抛出,则then()执行.如果它确实抛出,那么将handleCatch()决定是否then()被调用,因为如果handleCatch()重新抛出,则then()不会被调用,因为异常将立即抛出给调用者.如果handleCatch()可以优雅地处理问题,那么then()将被调用.
| 归档时间: |
|
| 查看次数: |
24126 次 |
| 最近记录: |