我从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