0

我有一堆嵌套函数从 ajax 调用返回延迟对象。这是我的代码的样子

function makeCalls() {
    var ajaxDfd1 = $.ajax(...);

    ajaxDfd1.then(function() {
        // want to execute after first call
        var ajaxDfd2 =  $.ajax(...);

        ajaxDfd2.done(function() {
            // want to execute after second call
        });

        return ajaxDfd2;
    });

    return ajaxDfd1;
}

makeCalls().done(function() {
    // stuff here was executed early
});

但是我的电话并没有按照我想要的顺序执行。里面的东西makeCalls().done()似乎是在ajaxDfd2实际完成之前调用的。

4

3 回答 3

2

巧克力,

您在回答中做出了错误的假设;即$.ajax()返回一个“常规对象”。

这是不正确的。

$.ajax()返回一个 jqXHR 对象,它是 Promise 的超集,即。它具有 Promise 的所有方法以及其他特定于 AJAX 的方法(例如.abort())。

如果返回的对象与$.ajax()Promise 不兼容,那么您问题中的代码会在尝试执行时抛出错误makeCalls().done(...)

您的函数首先执行的原因.done()是该函数返回外部jqXHR。

以下是实现您期望的行为的几种方法:

function makeCalls() {
    var dfrd = new Deferred();
    $.ajax(...).then(function() {
        $.ajax(...).done(dfrd.resolve);
    });
    return dfrd.promise();
}

makeCalls().done(function(data) {
    // ...
});

或者

function makeCalls(fn) {
    $.ajax(...).then(function() {
        $.ajax(...).done(fn);
    });
}

makeCalls(function(data) {
    // ...
});

你甚至可以尝试:

function makeCalls() {
    return $.ajax(...).then(function() {
        return $.ajax(...);
    });
}

makeCalls().done(function() {
    // ...
});
于 2013-02-22T21:59:34.663 回答
0

我知道我一定是搞错了,并且花了很长时间盯着这个: 我什么时候应该使用 jQuery deferred 的“then”方法,什么时候应该使用“pipe”方法?

后来我意识到我做不到

var dfdObj = $.ajax(...);
dfdObj.then(...);

return dfdObj;

这实际上并没有返回延迟对象。它返回一个 Ajax 对象,因为它是一个常规对象,所以它被自动归类为已解析,因此该.done()函数被提前调用。相反,如果我想返回一个var

var dfdObj = $.ajax(...).then(...);

return dfdObj;
于 2013-02-21T11:43:05.900 回答
0

你的代码是这样工作的:

function makeCalls() {
    var ajax1 = $.ajax(…);
    var ajax1and2 = ajax1.then(makeCall2);
    function makeCall2() {
        // want to execute after first call
        var ajax2 =  $.ajax(…);
        ajax2.done(after2);
        function after2() {
            // want to execute after second call
        });
        return ajax2;
    });
    return ajax1;
}

var ajax1 = makeCalls();
ajax1.done(function() {
    // stuff here was executed early
});

ajax1and2是您想要的then/调用的结果。pipe对它的回调将等待makeCall2(即ajax2)等待的结果ajax1。这将等于after2回调。

然而,您的makeCalls函数返回ajax1对象(您可以看到我也将它分配给了一个全局ajax1变量),并且makeCall2在您的第一个 ajax 完成后,将执行 the 和 done-callback。

因此,您需要返回ajax1and2延迟的:

function makeCalls() {
    return $.ajax(…).then(function() {
        return $.ajax(…).done(function() {
            // want to execute after second call
        });
    });
}

makeCalls().done(function() {
    // stuff here is now executed after second call as well
});
于 2013-02-22T23:23:26.220 回答