多个 ajax 调用的延迟调用

Deferred calls for multiple ajax calls

本文关键字:调用 延迟 多个 ajax      更新时间:2023-09-26

我有以下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();
    });

问题是 ajaxCall2 是在 ajaxcall1 成功之前调用的。你能帮我解决这个问题吗?我需要在前一个成功时一个接一个地进行 ajax 调用。

使用 $.when

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

首先,你可以直接返回 $.ajax 调用的结果,因为它们已经是承诺了(不需要中间的延迟):

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

简化。

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/


延伸阅读:

  • 如何使用 jquery 链接 ajax 调用
  • j查询延迟未按顺序调用解析/完成回调
  • jQuery 延迟 - 我需要管道还是链来实现此模式?

与其他答案相同,除了使用 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();

我在大量使用 SharePoint Web 服务时遇到了类似的问题 - 您通常需要从多个源中提取数据,然后才能继续工作。

为了解决这个问题,我将这种功能嵌入到我的 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);

请注意,与提供的许多其他解决方案不同,此方法不会强制对正在进行的调用进行单线程处理 - 每个调用仍将在环境允许的范围内以最快的速度运行,但只有在所有调用都完成后才会调用处理程序。 该组件还支持用户定义的请求数,因此您可以根据需要轻松强制单线程。 它还支持设置超时值,如果您的服务有点不稳定,则重试尝试。

我发现它对这类工作非常有用(而且非常容易理解)。