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

时间:2015-09-23 16:47:24

标签: javascript error-handling promise chaining

我有以下代码(http://jsfiddle.net/tj1eo86s/):

joint.all.js

如果拒绝承诺(2),则输出为:

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");
});

如何在链接承诺时获得相同的行为?

我尝试过(http://jsfiddle.net/7goh0ds9/):

OK1
KO2

但输出是:

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");
});

然后我尝试在错误回调(http://jsfiddle.net/cyx6mohy/)中抛出错误:

OK1
KO2
OK3

但现在我有:

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";
});

我实际上理解了所有这些行为,但我无法找到处理错误的解决方案,就像承诺是嵌套的一样。

2 个答案:

答案 0 :(得分:2)

如果您的问题是如何一般地使链接处理错误与任意嵌套完全相同,答案是您不能以通用的方式。链接是一种与任意嵌套完全不同的控制结构。

您可以设计一个与链接基本相同的嵌套。或者,如果您希望在链式世界中模拟嵌套结构中的特定错误处理行为,则“可能”能够在链接序列中使用适当的错误处理和控制流来实现这一点。注意,我说“可能”,因为它完全取决于嵌套序列的作用。您也可能无法使用纯链接来模拟它。

如果您的问题是如何使这个链式承诺序列在链中的这个特定承诺拒绝时生成此特定响应,那么这可能是可能的,但它将根据您的特定情况和期望结果进行编码,而不是一些通用的方式。

基本上,有理由使用链接,并且有理由使用嵌套和理由来使用两者的组合。像你一样,我更喜欢链接,因为控制流和可读性​​似乎更简单,所以我总是从头开始考虑这个结构,但在我的代码中肯定有时候我必须在操作的某些部分使用嵌套(通常是因为分支决策或某些类型的必要错误处理)。

答案 1 :(得分:1)

您可以拒绝索引作为参数,然后添加.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);
});