有许多关于如何在使用JavaScript Promise进行编程时使用“then”和“catch”的教程。然而,所有这些教程似乎都错过了一个重要的观点:从一个当时/ catch块返回来打破Promise链。让我们从一些同步代码开始来说明这个问题:如何从Promise的catch/then块返回
try {
someFunction();
} catch (err) {
if (!(err instanceof MyCustomError))
return -1;
}
someOtherFunction();
从本质上说,我测试捕获错误,如果它不是我期望我会返回给调用者的错误,否则程序继续执行。然而,这种逻辑不会与无极工作:
Promise.resolve(someFunction).then(function() {
console.log('someFunction should throw error');
return -2;
}).catch(function(err) {
if (err instanceof MyCustomError) {
return -1;
}
}).then(someOtherFunction);
这个逻辑用于一些我的单元测试,我想一个函数来以某种方式失败。即使我将catch改为一个block,我仍然无法打破一系列链接的Promise,因为从then/catch块返回的任何内容都将成为沿着链传播的Promise。
我不知道Promise能否实现这个逻辑;如果不是,为什么?我非常奇怪,一个Promise链永远不会被打破。谢谢!
2015年8月16日编辑: 根据到目前为止给出的答案,当时块返回的拒绝Promise将通过Promise链传播并跳过所有随后的块,直到被捕获(处理)。这种行为很好理解,因为它简单地模仿下面的同步码(方法1):
try {
Function1();
Function2();
Function3();
Function4();
} catch (err) {
// Assuming this err is thrown in Function1; Function2, Function3 and Function4 will not be executed
console.log(err);
}
不过,我问是在同步代码下面的情况下(方法2):
try {
Function1();
} catch(err) {
console.log(err); // Function1's error
return -1; // return immediately
}
try {
Function2();
} catch(err) {
console.log(err);
}
try {
Function3();
} catch(err) {
console.log(err);
}
try {
Function4();
} catch(err) {
console.log(err);
}
我想以不同的方式处理不同功能中出现的错误。我可能会捕获一个catch块中的所有错误,如方法1所示。但是这样我必须在catch块内部做一个大的switch语句来区分不同的错误;此外,如果由不同函数引发的错误没有共同的可切换属性,我将根本无法使用switch语句;在这种情况下,我必须为每个函数调用使用单独的try/catch块。方法2有时是唯一的选择。 Promise是否不支持这种方法与它的catch/catch语句?
为什么不''返回Promise.reject()'? – elclanrs
从当前块返回被拒绝的承诺将使得当时的块返回被拒绝的承诺,该承诺通过承诺链传播直到它被捕获。 – lixiang
根据您的澄清更新了我的答案。 – rrowland