我试图链接承诺,以便如果一个承诺被拒绝,链将破裂 . 我跟着previous SO question的线索并尝试将它应用于原生承诺,但我认为我误解了事情的运作方式 .
以下是我重写代码的方法:
Promise.resolve()
.then(function() {
return step(1)
.then(null, function() {
stepError(1);
});
})
.then(function() {
return step(2)
.then(null, function() {
stepError(2);
});
})
.then(function() {
return step(3)
.then(null, function() {
stepError(3);
});
});
function step(n) {
console.log('Step '+n);
return (n === 2) ? Promise.reject(n) : Promise.resolve(n);
}
function stepError(n) {
console.log('Error '+n);
return Promise.reject(n);
}
上面代码的输出是:
Step 1
Step 2
Error 2
Step 3
[UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): 2]
根据我的理解,第2步应该打破链条,不应该执行第3步 . 当步骤(2)返回被拒绝的promise时,stepError(2)按预期执行 . 但是因为它返回Promise.reject(2),所以下一个函数不应该被执行,并且因为最后没有catch,所以步骤2的被拒绝的承诺似乎 - 如预期的那样 - 被转发,直到它退出因为它没有找到任何处理程序链 .
我在这里想念的是什么?
这是一个可以玩的JSFiddle:https://jsfiddle.net/6p4t9xyk/
3 回答
看起来你过分复杂了 . 怎么样:
通常,“缩进然后”是反模式 . 所有“thens”应该在同一水平上 .
正如@ T.J.Crowder所说,你忘记了
return
错误处理程序的结果(或者来自它的throw
) . 为了解决这个问题,我建议你这样做要么
它会,但你不小心将拒绝转换为决议 .
关于promises的关键是每次对
then
的调用都会创建一个 new promise,它会根据then
回调的内容进行解析/拒绝,并且处理拒绝的回调会将拒绝转换为解决方案,除非故意不这样做 .所以在这里:
这样你就可以有错误处理程序来补偿错误 .
由于
stepError
返回拒绝,您可以通过添加return
继续拒绝:...或者,完全删除该处理程序:
...或者你可以在回调中
throw
,它会自动变成拒绝 .未处理的拒绝警告是由于没有消耗来自
stepError
的拒绝事实引起的 .这是一个返回
stepError
结果的示例: