延迟调用多个ajax调用

时间:2012-04-19 03:35:03

标签: javascript jquery jquery-deferred

我有以下JS方法:

    var foo = function() {
        var dfd = $.Deferred();
        console.log('foo');
        dfd.resolve();
        return dfd.promise();
    };
    var ajaxCall1 = function () {
        var dfd = $.Deferred();
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            url: 'xxxxxxx',
            data: { },
            success: function(response) {
                dfd.resolve();

            }
        });
        return dfd.promise();
    };
    var ajaxCall2 = function () {
        var dfd = $.Deferred();
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            url: 'xxxxxxx',
            data: {},
            success: function (response) {
                dfd.resolve();

            }
        });
        return dfd.promise();
    };
    var ajaxCall3 = function () {
        var dfd = $.Deferred();
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            url: 'xxxxxxx',
            data: {},
            success: function (response) {
                dfd.resolve();

            }
        });
        return dfd.promise();
    };

我通过这段代码打电话给他们:

    foo().done(function () {
        return ajaxCall1();
    }).done(function () {
       return  ajaxCall2();
    }).done(function () {
        return ajaxCall3();
    });

问题是在ajaxcall1成功发生之前调用了ajaxCall2。你能帮我解决这个问题吗?当前一个成功发生时,我需要逐个进行ajax调用。

5 个答案:

答案 0 :(得分:2)

使用$ .when

var deferredObject = $.ajax({});
$.when(deferredObject)
 .then(function(){
     var deferredobject2 = $.ajax({});
     $.when(deferredobject2)
      .then(function(){ alert('after 2nd ajax call');});

  }); 

答案 1 :(得分:1)

首先,您可以直接返回$ .ajax调用的结果,因为它们已经是promise(不需要中间Deferred):

var ajaxCall1 = function () {
    return $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        url: 'xxxxxxx',
        data: { }
    });
};
var ajaxCall2 = function () {
    return $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        url: 'xxxxxxx',
        data: {}
    });
};
var ajaxCall3 = function () {
    return $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        url: 'xxxxxxx',
        data: {}
    });
};

其次,您想要使用.pipe()来有效地链接呼叫:

foo().pipe(function () {
    return ajaxCall1();
}).pipe(function () {
    return  ajaxCall2();
}).pipe(function () {
    return ajaxCall3();
}).done(function() {
    // call1, call2 and call3 done in sequence
}).fail(function() {
    // one of the ajax requests failed
});

答案 2 :(得分:0)

简化。

function foo() {
    var dfd = $.Deferred();
    console.log('foo');
    dfd.resolve();
    return dfd.promise();
}

function ajaxCall1() {
    return $.ajax({
        type: 'POST',
        dataType: 'json',
        url: 'xxxxxxx',
        data: { },
        success: function(response) {
            console.log('ajaxCall1 success');
        }
    });
    return dfd.promise();
}

// and so on for ajaxCall2 and ajaxCall3

增强。

foo().done(function () {
    ajaxCall1().done(function () {
        ajaxCall2().done(function () {
            ajaxCall3();
        });
    });
});

http://jsfiddle.net/mattball/LxjDS/


进一步阅读:

答案 3 :(得分:0)

与其他答案相同,只是使用Frame.js

简化回调
var responses = [];
for(var i=0; i<1000; i++){
    Frame(function(callback){
        $.ajax('myserver.api', { 
            data:i, 
            type:'post', 
            complete:function(response) { 
                responses.push(response);
                callback();
            }
        });
    });
}
Frame.start();

通常情况下,使用这样的AJAX请求关闭浏览器会导致浏览器挂起,响应变量将按接收顺序返回,而不是发送给它们的原始顺序。在这里添加框架到混合把这一切排除在外。

或者你可以用它来平掉回调:

Frame(function(next){
    foo().done(next);
});
Frame(function(next){
    ajaxCall1().done(next);
});
Frame(function(next){
    ajaxCall2().done(next);
});
Frame(function(next){
    ajaxCall3().done(next);
});
Frame(function(next){
    //do more stuff
    next();
});
Frame.start();

答案 4 :(得分:0)

我在使用SharePoint网络服务方面遇到了类似的问题 - 在您能够继续工作之前,您经常需要从多个来源提取数据。

为了解决这个问题,我将这种功能嵌入到我的AJAX抽象库中。您可以轻松定义一个请求,该请求将在完成时触发一组处理程序。但是,每个请求都可以使用多个http调用进行定义。这是组件:

DPAJAX at DepressedPress.com

这个非常简单的示例创建了一个带有三个调用的请求,然后将这些信息按照调用顺序传递给单个处理程序:

    // The handler function
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) };

    // Create the pool
myPool = DP_AJAX.createPool();

    // Create the request
myRequest = DP_AJAX.createRequest(AddUp);

    // Add the calls to the request
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]);
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]);
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]);

    // Add the request to the pool
myPool.addRequest(myRequest);

请注意,与许多其他解决方案不同,此方法不会强制进行调用的单线程 - 每个调用仍然会像环境允许的那样快速运行,但只有在完成所有调用时才会调用处理程序。该组件还支持用户定义的请求数,因此您可以根据需要轻松强制执行单线程。它还支持设置超时值和重试尝试,如果您的服务有点冒险。

我发现这种工作非常有用(并且非常简单易懂)。