Jquery嵌套延迟等待AJAX​​响应

时间:2017-04-20 14:56:50

标签: jquery ajax deferred

具有延迟的函数调用另一个具有延迟内部函数的函数:

var state = true;

var construct = function() {
    var dfd = $.Deferred();
    dfd
        .then(function() {
            return wakeUp();
        })
        .then(function() {
            return makeCoffee();
        })
        .then(function() {
            return conquireTheWorld();
        })
        .then(function() {
            console.log("I'm done");
        });
    dfd.resolve();
}

var wakeUp           = function() {console.log('Woke up');}

var makeCoffee       = function() {console.log('Made some coffee');}

var conquireTheWorld = function() {
    var dfd = $.Deferred();
    if (state) {
        dfd.then(function() {
            return $.when(someAjax('http://babeljs.io')).done(function() {console.log("World done with AJAX");})
        });
    } else {
        dfd.then(function() {
            console.log("World done in a simple way");
        });
    }
    dfd
        .then(function() {
            console.log("Moon done too");
        });
    return dfd.resolve();
}

var someAjax = function(url) {
    return $.ajax({
        type: 'GET',
        url: url
    });
}

不幸的是,在这种情况下它会卡在conquireTheWorld函数中:.done部分$.when根本没有运行,而其他部分则在父项之后执行。有控制台输出:

Woke up
Made some coffee
Moon done too //executed before ajax request complete
I'm done //executed before conquerTheWorld function ajax
World done with AJAX

如何等待ajax请求?我尝试删除$ .when并在另一个.then语句中处理(没有更改),或者返回dfd.promise()而不是dfd.resolve()(它停留在该函数中)。如何正确地做到这一点?

1 个答案:

答案 0 :(得分:1)

承诺:

var p = promise.then(fnA).then(fnB).then(fnC);

链可以在单个表达式中形成如下:

var p;
p = promise.then(fnA);
p = p.then(fnB);
p = p.then(fnC);

以下是等价物 - 形成一条链" by assigment" :

fnA

以下不等效 - fnBfnCpromise仅依赖于promise.then(fnA); promise.then(fnB); promise.then(fnC); ,而不是彼此依赖。

conquireTheWorld()

问题的console.log("World done with AJAX")是用"不等同的"写的。图案。

console.log("Moon done too")取决于AJAX上的初始承诺(实际上是延迟的)

与此同时,调用者中的console.log("I'm done")(和conquireTheWorld())都只依赖于初始承诺,并且通过AJAX延迟消息赢得竞赛

要修复,请将var conquireTheWorld = function() { var promise = $.when(); // shorthand way to create a resolved jQuery promise. if (state) { promise = promise.then(function() { return someAjax('http://babeljs.io').then(function() { console.log("World done with AJAX"); }); }); } else { promise = promise.then(function() { console.log("World done in a simple way"); }); } promise = promise.then(function() { console.log("Moon done too"); }); return promise; } 转换为"等效的"模式通过分配和返回结果承诺,而不是最初的承诺。

编辑:

完整:

{{1}}

有更好的方法可以实现相同目的,但这是问题中代码的更正版本。