以干净的方式打破 javascript 承诺链

2024-03-03

我正在尝试将承诺串联起来,这样如果一个承诺被拒绝,链条就会断裂。我跟随一个人的线索上一个SO问题 https://stackoverflow.com/questions/20714460/break-promise-chain-and-call-a-function-based-on-the-step-in-the-chain-where-it并尝试将其应用于本机承诺,但我认为我误解了事物的工作方式。

这是我重写代码的方式:

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 不应该执行。当step(2)返回被拒绝的promise时,stepError(2)将按预期执行。但由于它返回 Promise.reject(2),所以下一个 then 中的函数不应该被执行,并且由于最后没有 catch,所以步骤 2 中被拒绝的 Promise 似乎会像预期的那样被转发,直到它退出链,因为它没有找到任何处理程序。

我在这里缺少什么?

这是一个可以使用的 JSFiddle:https://jsfiddle.net/6p4t9xyk/ https://jsfiddle.net/6p4t9xyk/


根据我的理解,第 2 步应该打破链条......

It would,但你不小心把拒绝变成了解决方案。

关于承诺的关键是每次调用then创建一个new根据以下内容解决/拒绝的承诺then回调会执行此操作,并且处理拒绝的回调会将拒绝转换为解决方案,除非故意这样做。

So here:

return step(2)
    .then(null, function() {  // This handler converts the
        stepError(2);         // rejection into a resolution
    });                       // with the value `undefined`

这样您就可以拥有补偿错误的错误处理程序。

Since stepError返回拒绝,您可以通过添加一个来继续拒绝return:

return step(2)
    .then(null, function() {
        return stepError(2);  // Added `return`
    });

...或者,完全删除该处理程序:

return step(2);

...或者你可以throw在回调中,这会自动变成拒绝。

未处理的拒绝警告是由于没有任何内容消耗来自的拒绝而引起的stepError.


这是一个返回结果的示例stepError:

Promise.resolve()
    .then(function() {
        return step(1)
            .then(null, function() {
                return stepError(1); // Added `return`
            });
    })
    .then(function() {
        return step(2)
            .then(null, function() {
                return stepError(2); // Added `return`
            });
    })
    .then(function() {
        return step(3)
            .then(null, function() {
                return stepError(3); // Added `return`
            });
    });

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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以干净的方式打破 javascript 承诺链 的相关文章

随机推荐