有許多關於如何在使用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