我從E6 Promises開始。我非常喜歡它們,但是有一個關於錯誤處理的重要概念,我不明白,並且希望能夠澄清一些問題。ES6承諾錯誤沒有按預期冒泡
假設以下簡單的函數返回一個承諾:
function promiseString(str, timeout, doResolve) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (doResolve) {
resolve(str);
} else {
reject(new Error("Rejecting " + str));
}
}, timeout);
});
}
這是很簡單的,只是返回傳遞給它的字符串承諾,並承諾原因有待解決或拒絕(基於第三個參數)在「超時」毫秒。
我完全可以預期如下消耗這樣的:
promiseString("One", 100, true)
.then((str) => { console.log("First then is " + str); return promiseString(str + " two", 100, true); })
.then((str) => { console.log("Second then is " + str); return promiseString(str + " three", 100, true); })
.then((str) => console.log(str))
.catch((err) => console.error(err));
如果改變任何在這條產業鏈的調用的第三個參數,從「真」到「假」,如預期的那樣引起了我的錯誤併發送到console.error()。
不過,現在想象一下以下(同樣愚蠢的)功能,構建一個充滿希望的對象:
function DoublePromiser(str1, str2, doResolve) {
this.promise = new Promise((resolve, reject) => {
promiseString(str1, 100, doResolve)
.then((s1) => promiseString(s1 + str2, 100, doResolve))
.then((s2) => resolve(s2));
});
}
現在我消耗這段代碼如下,一切都解決,並沒有拒絕試想一下,(doResolve設爲真):
var dp = new DoublePromiser("Big", "Promise", true);
dp.promise
.then((s) => console.log("DoublePromise: " + s))
.catch((err)=>console.log("I did catch: ", err.message));
正如所預料的,我在控制檯看到以下內容:
DoublePromise: BigPromise
不過,現在我改變消費密碼,設置doResolve爲「假」(這將導致我的諾言常規拒絕):因爲我是如何錯誤應該「冒泡」,我希望瞭解
var dp = new DoublePromiser("Big", "Promise", false);
dp.promise
.then((s) => console.log("DoublePromise: " + s))
.catch((err)=>console.log("I did catch: ", err.message));
控制檯登錄如下:
I did catch: Rejecting Big
但它沒有。相反,控制檯顯示未捕獲的錯誤:
Uncaught (in promise) Error: Rejecting Big
我只得到我期望(和希望)如果我添加一個catch在DoublePromiser鏈的結尾,就像這樣:
function DoublePromiser(str1, str2, doResolve) {
this.promise = new Promise((resolve, reject) => {
promiseString(str1, 100, doResolve)
.then((s1) => promiseString(s1 + str2, 100, doResolve))
.then((s2) => resolve(s2))
.catch((err) => reject(err)); // ADDING THIS TO MAKE IT WORK
});
}
現在我得到了我所期望的,錯誤並未被捕獲。但是,這似乎與錯誤冒起來的整個想法相反,並且爲了重新拒絕同樣的錯誤而發現錯誤似乎很奇怪。
我錯過了一個簡單的工作方式嗎?
我錯過了一些基本概念?
這些100%的理論問題使用不構成實際問題的代碼,在堆棧溢出方面效果不佳。 – jfriend00
另外,你正在使用承諾構造函數反模式:https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns – jfriend00
@estus - 我編輯了他們的標題。 – jfriend00