javascript - 为什么 Promise 链在这个例子中工作,没有抛出错误
问题描述
所以在第一个例子中,链一直执行到最后一个console.log,没有错误,但在第二个例子中,类似的,它确实出错了。为什么会发生这种情况,我能否以某种方式使第一个示例也引发错误?
我只知道它与向对象添加函数有关,因为如果test
未定义,则链会中断,但我无法理解如何访问对象中不存在的键不会导致错误。
编辑:我刚刚意识到我的脑残。自然地访问test.something
返回undefined
而不是错误。
// EXAMPLE 1: Weird
var test = {};
test.f1 = function(result) {
return new Promise(function(resolve, reject) {
console.log("result", result);
resolve(1)
});
}
test.f2 = function(result) {
return new Promise(function(resolve, reject) {
console.log("result", result);
resolve(2)
});
}
test.f3 = function(result) {
return new Promise(function(resolve, reject) {
console.log("result", result);
resolve(3)
});
}
test.f4 = function(result) {
console.log("result", result);
}
test.f1(1)
.then(test.f2)
.then(test.f3)
.then(test.shouldCauseError)
.then(test.f4)
// EXAMPLE 2: As expected
new Promise(function(resolve, reject) {
resolve(1);
})
.then(function(result) {
return new Promise(function(resolve, reject) {
resolve(2)
});
})
.then(function(result) {
return new Promise(function(resolve, reject) {
resolve(3)
});
})
.then(shouldCauseError)
.then(function(result) {
console.log("result:", result);
});
解决方案
.then
最多接受两个参数。第一个参数,如果存在,则在上层 Promise 已解决时运行。第二个参数,如果存在,则在上层 Promise 被拒绝时运行。
undefined
允许作为第一个参数(或作为两个参数)传递-.then
因为不存在任何参数,所以上层 Promise 将通过未.then
更改的传递。
(也,.then(undefined, fn)
等价于.catch(fn)
)
所以,你的
.then(test.shouldCauseError)
传递undefined
到.then
,这意味着上面的 Promise.then
没有修改(并且没有抛出)传递 - 它进入.then
链中的下一个,就好像.then(test.shouldCauseError)
不在那里一样。
由于传递undefined
到.then
非常好,您需要一些其他方法来创建错误 - 可能将您传递给.then
s 的所有内容包装在一个函数中,该函数检查传递的表达式是否实际上是一个函数,如果不是,则返回一个抛出的函数:
.then(validate(test.shouldCauseError))
// EXAMPLE 1: Weird
var test = {};
test.f1 = function(result) {
return new Promise(function(resolve, reject) {
console.log("result", result);
resolve(1)
});
}
test.f2 = function(result) {
return new Promise(function(resolve, reject) {
console.log("result", result);
resolve(2)
});
}
test.f3 = function(result) {
return new Promise(function(resolve, reject) {
console.log("result", result);
resolve(3)
});
}
test.f4 = function(result) {
console.log("result", result);
}
const validate = arg => {
if (typeof arg !== 'function') {
return () => {
throw new Error();
}
}
return arg;
};
test.f1(1)
.then(validate(test.f2))
.then(validate(test.f3))
.then(validate(test.shouldCauseError))
.then(validate(test.f4))
.catch((err) => {
console.log('Error caught');
});
您还可以创建test
一个代理,在访问目标对象上不存在的属性时返回一个抛出函数。
但这些都是奇怪的解决方案,因为正在解决的“问题”在 JS 中不被视为问题。如果你想避免这类错误,我更喜欢使用 Typescript 之类的东西来确保我传递的内容是正确的类型,而不是undefined
.
推荐阅读
- excel - Expiry Date Comparison and Marking Groups of Rows in a Table
- android - 加载数据的 ProgressDialog 的替代方案?
- android - MVVM:根据用例使用不同的 ViewModel 实现
- razor - Is there a way to write an embedded LESS code within a Razor View?
- octave - Please specify the error in this octave code
- c - 如何使文件指针指向文件的开头?
- python - TypeError:无效的前景 RGBA 参数
- java - 未从相关 JAR 应用程序生成日志文件
- python - 大小为 (100, 1) 和 (100,) 的 numpy 数组有什么区别?
- python - 如何在用户定义的函数(又名 udf)中返回 Pandas.Series?