从承诺链的中间解决

时间:2015-12-27 12:05:06

标签: javascript node.js q

在我的代码中,我使用Q库链接多个API调用,如下所示:

function long_promise_chain() {
    var q = Q.defer();
    call_api_batch1()
        .then(function(v) {
            if (v.bar) {
                q.resolve();
            } else {
                return call_api_batch_2();
            }
        })
        .then(function(v) {
            if (v.bar) {
                q.resolve();
            } else {
                return call_api_batch_3();
            }
        })
        .then(function(v) {
            if (v.bar) {
                q.resolve();
            } else {
                return call_api_batch_3();
            }
        }, function(err) {
            console.log("err: " + err);
        });
    return q.promise
}

我看到即使链在第一批之后被解析,下一个then块也会运行并导致错误 - 尝试访问未定义的变量然后调用函数(错误)块。 / p>

你能否提出正确的解决方法。

更新: 问题是,如果第一个q.resolve()被调用,我不希望链中的下一个.then被触发。虽然正确调用了q.resolve并将控制权返回给调用者,但是打印时出现错误,因为在第二种情况下,没有' v'并且错误是“无法读取”未定义的属性栏'在测试v.bar时。

2 个答案:

答案 0 :(得分:1)

我希望我理解你。这是你想要的吗?:

function long_promise_chain() {
    var q = Q.defer();
    var allDone = false;
    call_api_batch1()
        .then(function(v) {
            if (v.bar) {
                q.resolve();
                allDone = true;
            } else {
                return call_api_batch_2();
            }
        })
        .then(function(v) {
            if (!allDone) {
                if (v.bar) {
                    q.resolve();
                    allDone = true;
                } else {
                    return call_api_batch_3();
                }
            }
        })
        .then(function(v) {
            if (!allDone) {
                if (v.bar) {
                    q.resolve();
                    allDone = true;
                } else {
                    return call_api_batch_3();
                }
            }
        }, function(err) {
            console.log("err: " + err);
        });
    return q.promise
}

答案 1 :(得分:0)

在您的情况下,有两个单独的resolve来处理。

  1. 首先是包含延迟对象的小写q。这是您从long_promise_chain返回的承诺。
  2. 第二,你链的每个阶段的承诺。即,从链中的每个then调用返回到后续then的承诺。
  3. 您可以直接在q上调用方法来解决或拒绝q。您可以通过then块中返回Q.resolve()Q.reject() 来解决或拒绝then承诺。

    以下是一个示例:

    喜爱 在我的代码中,我使用Q库链接多个API调用,如下所示:

    function long_promise_chain() {
        var q = Q.defer();
        call_api_batch1()
            .then(function(v) {
                if (condition) {
                    q.resolve();
                    return Q.reject();
                } else {
                    return call_api_batch_2();
                }
            })
            .then(function(v) {
                if (condition) {
                    q.resolve();
                    return Q.reject();
                } else {
                    return call_api_batch_3();
                }
            })
            .then(function(v) {
                if (condition) {
                    q.resolve();
                    return Q.reject();
                } else {
                    return call_api_batch_3();
                }
            }, function(err) {
                console.log("err: " + err);
            });
        return q.promise
    }