我是承诺的新手,但据我所知,.catch
通常属于承诺链的末尾:
promiseFunc()
.then( ... )
.then( ... )
.catch( // catch any errors along the chain )
如果承诺在功能之间分开怎么办?我是否抓住了每个功能的结尾?
func1 () {
promiseFunc1()
.then((result) => {
promiseFunc2()
)
// should I .catch here?
}
func2 () {
func1()
.then((result) => {
// do stuff
})
.catch(console.log.bind(console)); // this also catches errors from func1
}
也许这是另一个错误的症状(我喜欢听错,如果我这样做错了),但是当我尝试捕捉到func1的结尾时,我最终会到达.then
func2的块,result = undefined
。删除func1
中的catch后,它可以正常工作 - 但是func1应该期望任何调用它的函数捕获它的错误。
答案 0 :(得分:2)
.catch()
非常像try/catch
。你应.catch()
在任何你想要或需要处理错误的地方,记录一些东西或改变链的过程。
如果您想要的是承诺链在发生错误时中止,那么您只需将一个.catch()
放在链的最后并处理错误。
另一方面,如果你有链的一些子部分,如果它有拒绝你想要做一些不同的事情并允许链继续或采取不同的路径,那么你需要{ {1}}如果出现错误,您希望影响事物的那个级别。
最后全部或没有任何捕获
所以,假设您有四个函数都返回承诺。
如果你这样做:
.catch()
然后,如果你的四个承诺中的任何一个拒绝,那么链的其余部分将中止,它将跳到你的a().then(b).then(c).then(d).then(finalResult => {
// final result here
}).catch(err => {
// deal with error here
});
。对于某些操作,这是期望的行为。如果您打算从外部服务器获取一些数据,使用该数据然后从另一个外部服务器获取一些其他数据,然后将该数据写入磁盘,整个过程几乎全有或全无。如果前面的任何步骤失败,那么在整个操作失败时你无法做任何其他事情,你也可以在最后使用一个.catch()
并报告错误。
干预Catch以在出错时更改行为中间链
On,另一方面假设您有从某个外部服务器获取某些数据的情况,但如果该服务器已关闭,则您希望从备用服务器获取数据。在这种情况下,您希望从第一次获取中捕获错误并尝试其他操作。所以,你在第一步使用.catch()
并尝试不同的东西:
.catch()
记录和Rethrow
在构建其他人将使用的子系统时,记录某些类型的错误通常很有用。因此,即使整个承诺链可能全部或全部,您仍然可能希望在链中更早地记录错误,然后重新抛出错误,以便链继续处于拒绝状态:
fetch1().catch(fetch2).then(b).then(c).then(finalResult => {
// final result here
}).catch(err => {
// deal with error here
});
然后来电者将会这样做:
function someFuncOthersUse() {
return a().then(b).then(c).catch(err => {
// you want your own logging any time a or b or c rejects
console.log("Error on fetchB", err);
throw err;
});
}