简体   繁体   English

有没有办法在处理错误时链接promises,好像promises是嵌套的?

[英]Is there any way to chain promises while handling errors as if promises were nested?

I have the following code ( http://jsfiddle.net/tj1eo86s/ ): 我有以下代码( http://jsfiddle.net/tj1eo86s/ ):

promise(1).then(function() {
    console.log("OK1");
    promise(2).then(function() {
        console.log("OK2");
        promise(3).then(function() {
            console.log("OK3");
        }, function() {
            console.log("KO3");
        });
    }, function() {
        console.log("KO2");
    });
}, function() {
    console.log("KO1");
});

If promise(2) is rejected, the output will be: 如果promise(2)被拒绝,输出将是:

OK1
KO2

How can I obtain the same behavior while chaining the promises? 在链接承诺时如何获得相同的行为?

I tried with ( http://jsfiddle.net/7goh0ds9/ ): 我试过( http://jsfiddle.net/7goh0ds9/ ):

promise(1)
.then(function() {
    console.log("OK1");
    return promise(2);
}, function() {
    console.log("KO1");
})
.then(function() {
    console.log("OK2");
    return promise(3);
}, function() {
    console.log("KO2");
})
.then(function() {
    console.log("OK3");
}, function() {
    console.log("KO3");
});

But the output is: 但输出是:

OK1
KO2
OK3

Then I tried to throw an error in the error callbacks ( http://jsfiddle.net/cyx6mohy/ ): 然后我试图在错误回调中抛出一个错误( http://jsfiddle.net/cyx6mohy/ ):

promise(1)
.then(function() {
    console.log("OK1");
    return promise(2);
}, function() {
    console.log("KO1");
    throw "KO1";
})
.then(function() {
    console.log("OK2");
    return promise(3);
}, function() {
    console.log("KO2");
    throw "KO2";
})
.then(function() {
    console.log("OK3");
}, function() {
    console.log("KO3");
    throw "KO3";
});

But now I have: 但现在我有:

OK1
KO2
KO3

I actually understand all those behaviors, but I have not been able to find a solution to handle errors as if promises were nested. 我实际上理解了所有这些行为,但我无法找到处理错误的解决方案,就像promises嵌套一样。

If your question is how to I generically make chaining handle errors the exact same way as arbitrary nesting, the answer is that you can't in a generic way. 如果你的问题是如何一般地使链接处理错误与任意嵌套完全相同,答案是你不能以通用的方式。 Chaining is a fundamentally different control structure than arbitrary nesting. 链接是一种与任意嵌套完全不同的控制结构。

You could design a nesting that had fundamentally the same behavior as chaining. 您可以设计一个与链接基本相同的嵌套。 Or, if you had a specific error handling behavior from a nested structure that you wanted to emulate in a chained world, you "might" be able to use the appropriate error handling and control flow in a chained sequence to make that happen. 或者,如果您希望在链式世界中模拟嵌套结构中的特定错误处理行为,则“可能”能够在链接序列中使用适当的错误处理和控制流来实现这一点。 Note, I say "might" because it depends entirely upon what the nested sequence was doing. 注意,我说“可能”,因为它完全取决于嵌套序列的作用。 You also might not be able to emulate it with pure chaining. 您也可能无法使用纯链接来模拟它。

If your question is how do I make this sequence of chained promises generate this specific response when this specific promise in the chain rejects, then that might be possible, but it would be coded for your specific circumstance and desired outcome, not in some generic way. 如果您的问题是如何使这个链式承诺序列在链中的特定承诺拒绝时生成此特定响应,那么这可能是可能的,但它将根据您的特定情况和期望结果进行编码,而不是以某种通用方式编码。

Basically, there are reasons to use chaining and there are reasons to use nesting and reasons to use a combination of the two. 基本上,有理由使用链接,并且有理由使用嵌套和理由来使用两者的组合。 Like you, I prefer chaining because the control flow and readability just seems simpler, so I always start out with that structure in mind, but there are definitely times in my code where I have to use nesting for some part of the operation (often because of branching decisions or certain types of required error handling). 像你一样,我更喜欢链接,因为控制流和可读性​​似乎更简单,所以我总是从头开始考虑这个结构,但在我的代码中肯定有时候我必须在操作的某些部分使用嵌套(通常是因为分支决策或某些类型的必要错误处理)。

You can reject with the index as argument, then add a .catch and handle the error there: 您可以拒绝索引作为参数,然后添加.catch并在那里处理错误:

var breakOnPromise = 2;

function promise(i) {
    return new Promise(function(resolve, reject) {
        if (i == breakOnPromise) {
            reject(i); // pass index to catch
        } else {
            resolve();
        }
    });
}

promise(1).then(function() {
    console.log("OK1");
    return promise(2);
}).then(function() {
    console.log("OK2");
    return promise(3);
}).then(function() {
    console.log("OK3");
}).catch(function(i) {
    // This is just for your case,
    // but you could use an `if` statement
    var err = ["KO1", "KO2", "KO3"][i - 1];
    console.log(err);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM