您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

断开promise链,并根据该链中被破坏(被拒绝)的步骤调用函数

断开promise链,并根据该链中被破坏(被拒绝)的步骤调用函数

您的代码无法按预期工作的原因是它实际上在做与您认为的有所不同的事情。

假设您有以下内容

stepOne()
.then(stepTwo, handleErrorOne)
.then(stepThree, handleErrorTwo)
.then(null, handleErrorThree);

为了更好地了解正在发生的事情,让我们假设这是带有try/ catch块的同步代码

try {
    try {
        try {
            var a = stepOne();
        } catch(e1) {
            a = handleErrorOne(e1);
        }
        var b = stepTwo(a);
    } catch(e2) {
        b = handleErrorTwo(e2);
    }
    var c = stepThree(b);
} catch(e3) {
    c = handleErrorThree(e3);
}

onRejected处理程序(的第二个参数then)本质上是一个纠错机制(如catch块)。如果抛出错误handleErrorOne,它将被下一个catch块(catch(e2))捕获,依此类推。

这显然不是您想要的。

假设无论发生什么问题,我们都希望整个解决方案链失败:

stepOne()
.then(function(a) {
    return stepTwo(a).then(null, handleErrorTwo);
}, handleErrorOne)
.then(function(b) {
    return stepThree(b).then(null, handleErrorThree);
});

注意:我们可以保留handleErrorOne它的位置,因为只有在stepOne拒绝时才会调用它(它是链中的第一个函数,因此我们知道如果链在此刻被拒绝,那只能是由于该函数的诺言而已) 。

重要的变化是其他功能错误处理程序不属于主要的Promise链。相反,每个步骤都有其自己的“子链”,onRejected只有在该步骤被拒绝(但主链无法直接到达)时才调用该子链。

这样做的原因是onFulfilledonRejected都是then方法的可选参数。如果兑现了一个承诺(即已解决),并且then链中的下一个没有onFulfilled处理程序,则链将继续进行,直到有一个具有此类处理程序的处理程序为止。

这意味着以下两行是等效的:

stepOne().then(stepTwo, handleErrorOne)
stepOne().then(null, handleErrorOne).then(stepTwo)

但是以下行 并不 等同于以上两行:

stepOne().then(stepTwo).then(null, handleErrorOne)

Angular的promise库$q基于kriskowal的Q库(具有更丰富的API,但包含您可以在中找到的所有内容$q)。GitHub上的Q的api文档可能很有用。Q实现了Promises / A +规范,该规范详细介绍了如何then以及如何实现承诺解决行为。

编辑:

还要记住,如果您想打破错误处理程序中的链条,它需要返回被拒绝的承诺或引发错误(将被捕获并自动包裹在被拒绝的承诺中)。如果您不返回承诺,then则将返回值包装在为您解决的承诺中。

其他 2022/1/1 18:15:46 有512人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶