以干净的方式打破 javascript 承诺链 [英] Break javascript promise chain in a clean way

查看:43
本文介绍了以干净的方式打破 javascript 承诺链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试链接承诺,以便在一个承诺被拒绝时链条会中断.我遵循了 previous SO question 并试图将其应用于本机承诺,但我认为我误解了事情的运作方式.

I am trying to chain promises so that the chain will break if one promise is rejected. I followed the leads of a previous SO question and tried to apply it to native promises, but I think I am misunderstanding the way things work.

以下是我重写代码的方式:

Here is how I have rewritten the code:

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 似乎 - 正如预期的 - 被转发,直到它退出链,因为它没有找到任何处理程序.

In my understanding, step 2 should break the chain and step 3 should not be executed. When step(2) returns a rejected promise, stepError(2) is executed as expected. But since it returns Promise.reject(2), the function in the next then should not be executed, and since there is not catch in the end, the rejected promise of step 2 seems - as expected - to be forwarded until it exits the chain because it didn't find any handler.

我在这里遗漏了什么?

这里有一个 JSFiddle 可以玩:https://jsfiddle.net/6p4t9xyk/

Here is a JSFiddle to play with: https://jsfiddle.net/6p4t9xyk/

推荐答案

据我所知,第 2 步应该打破链条......

In my understanding, step 2 should break the chain...

,但您不小心将拒绝转化为解决方案.

It would, but you've accidentally converted that rejection into a resolution.

promise 的关键在于每次对 then 的调用都会创建一个 new 承诺,该承诺根据 then 回调的内容进行解析/拒绝(s) do,并且处理拒绝的回调会将该拒绝转换为解决方案,除非它有意这样做.

The key thing about promises is that every call to then creates a new promise which is resolved/rejected based on what the then callback(s) do, and the callback processing a rejection converts that rejection into a resolution unless it intentionally does otherwise.

所以在这里:

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

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

That's so that you can have error handlers that compensate for the error.

由于 stepError 返回一个拒绝,你可以通过添加一个 return 来继续拒绝:

Since stepError returns a rejection, you could continue the rejection by just adding a return:

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

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

...or alternately, remove that handler entirely:

return step(2);

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

...or you could throw in the callback, which is automatically turned into a rejection.

未处理的拒绝警告是由没有消耗来自stepError 的拒绝这一事实引起的.

The unhandled rejection warning is caused by the fact nothing consumes the rejection from stepError.

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

Here's an example returning the result of 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);
}

这篇关于以干净的方式打破 javascript 承诺链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆