有很多关于在使用 JavaScript Promise 编程时如何使用“then”和“catch”的教程。然而,所有这些教程似乎都忽略了一个重要的点:从 then/catch 块返回以打破 Promise 链。让我们从一些同步代码开始来说明这个问题:
try {
someFunction();
} catch (err) {
if (!(err instanceof MyCustomError))
return -1;
}
someOtherFunction();
本质上,我正在测试一个捕获的错误,如果它不是我期望的错误,我将返回给调用者,否则程序将继续。但是,此逻辑不适用于 Promise:
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 更改为 then 块,我仍然无法破坏一系列链接的 Promise,因为从 then/catch 块返回的任何内容都将成为沿链传播的 Promise。
不知道Promise是否能够实现这个逻辑;如果不是,为什么?Promise 链永远不会被破坏,这对我来说很奇怪。谢谢!
2015 年 8 月 16 日编辑:根据目前给出的答案,then 块返回的被拒绝 Promise 将通过 Promise 链传播并跳过所有后续 then 块,直到被捕获(处理)。这种行为很好理解,因为它只是模仿了以下同步代码(方法 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);
}
我想以不同的方式处理不同功能中引发的错误。如方法 1 所示,我有可能在一个 catch 块中捕获所有错误。但是那样我必须在 catch 块中创建一个大的 switch 语句来区分不同的错误;此外,如果不同函数抛出的错误没有共同的可切换属性,我将根本无法使用 switch 语句;在这种情况下,我必须为每个函数调用使用单独的 try/catch 块。方法 2 有时是唯一的选择。Promise 的 then/catch 语句是否不支持这种方法?