【问题标题】:Wait till all multiple asynchronous ajax call are completed等到所有多个异步ajax调用完成
【发布时间】:2016-04-18 22:18:42
【问题描述】:

您好,我有多个 ajax 调用,我想做的是异步触发所有它们,然后等到它们都完成后再处理返回的数据。我尝试使用 $.when 但无济于事。这是我的代码:

//form_identifier_list is my flag to get the multiple forms in my html page
function test(form_identifier_list){
    var deffereds = [];

    $.each(form_identifier_list, function(key,value){
        var this_form = $(this).parents('.ajaxed_form');
        deffereds.push( $.post($(this_form).attr("action"), $(this_form).serializeForm()) );
    });

    $.when.apply($, deffereds).done(function(){
        //how to output response obj?? i tried console.log(data) to no avail
    }).fail(function(){

    }).always(function(){

    });
}

我还注意到我的 ajax 请求没有响应(我在浏览器上进行了验证)。

有没有办法让多个 ajax 调用异步触发,然后等到所有调用完成后再访问数据?

谢谢

【问题讨论】:

  • 你的代码看起来没问题,除了你在承诺链上使用了.always()。您需要描述代码是如何失败的,和/或产生的任何错误。
  • I also noticed my ajax requests do not have reponse - 如果您的 ajax 请求没有响应 - 那么您希望登录您的 done 函数?
  • 当我多次调用我的 $.post 时,最后一个会有响应。我会把我的代码供你参考

标签: javascript jquery ajax asynchronous


【解决方案1】:

when的jquery页面中,有一段说:

在传递多个 Deferred 对象的情况下 jQuery.when(),该方法从一个新的“master”返回 Promise 跟踪所有 Deferred 的聚合状态的 Deferred 对象 已经通过了。

ajax page上也有这个

从 jQuery 1.5 开始,由 $.ajax() 返回的 jqXHR 对象实现了 承诺接口

所以我们可以将ajax 的返回值分配给一个变量,然后将这些变量传递给.when

要稍微扩展 .when 页面上给出的示例并集成任意数量的 ajax 调用,您可以执行以下操作:

var ajaxes = [];
for(var i=0; i<10; i++) {
    ajaxes.push($.ajax('a.php', {data: {t: i}}));
}
$.when.apply($, ajaxes)
    .done(function(){
        for(var i=0;i<arguments.length; i++) {
            $('#output').append(arguments[i] + "<br>");
        };
    });

如果你有一个已知数量的 ajax 调用,它会变得更简单...你可以做更多这样的事情:

var a1 = $.ajax(...);
var a2 = $.ajax(...);
var a3 = $.ajax(...);
$.when(a1,a2,a3).done(function(o1, o2, o3) {
  $('#output').append(o1).append(o2).append(o3);
});

第一个例子基本上是做同样的事情。

【讨论】:

  • 先生您好。大卫,所以我不应该在合并我的 ajax 请求时使用 $.post?
  • 我在这里看不到任何内容 - OP 已经知道如何使用 $.when.apply。他的问题出在其他地方。
  • 是的,您应该可以使用post,该页面上有一个部分还说 1.5+ 实现了 Promise 接口。
  • @Alnitak 是对的,很抱歉重述您所做的一切。我认为主要问题是当您执行.apply 时,您没有将 jQuery 作为您的“this”对象传递。我怀疑这很重要,因为您正在链接。
  • 是的,他是 - $.when.apply($, ...),无论如何 jQuery 并不关心。问题在于$.ajax() 的响应失败。
【解决方案2】:

可以异步调用多个 JavaScript 函数(例如 Ajax 函数),等待每个函数完成,然后使用 setInterval 继续(例如访问数据)。

考虑三个 JavaScript 函数 (i=0,1,2)。每个函数执行相同数量的操作 (10)。系统启动后(T_0),每个函数都有一个开始(T_(3i+2)或〖T〗_2,〖T〗_5和〖T〗8),一个执行十次的操作(T (3i+3)或〖T〗_3,〖T〗_6和〖T〗9),以及结尾(T(3i+4)或〖T〗_4,〖 T〗_7 和〖T〗_10)。当功能准备好开始时,功能可以以任何顺序开始。每个函数执行其操作十次。当每个函数都执行完毕后,系统继续(T_1),这三个函数可能会再次执行。

图 1:用于同步三个函数调用的 Petri 网模型

setInterval 执行的函数如下:

  1. 选择要执行的 (ajax) 函数,并执行该函数。例如图1中的T_3、T_6和〖T〗_9中的每一个都可能代表对一个(ajax)函数的函数调用,该函数被调用了十次。
  2. 如果每个 (ajax) 函数都已完成其任务,则该函数继续执行并清除区间对象。

考虑以下示例代码 sn-p:

var s1=false, s2=false, s3=false;
// a1 (an Ajax function) sets s1 to true if it is finished
function a1() { …}
// a2 (an Ajax function) sets s2 to true if it is finished 
function a2() {…}
// a3 (an Ajax function) sets s3 to true if it is finished
function a3() {…}
// fcon is the function to execute when a1, a2 and a3 has finished.
function fcon() {…}
function myFunction() {
  var af = [], i;
  If (s1) af[af.length] = 1;
  If (s2) af[af.length] = 2;
  If (s3) af[af.length] = 3;
  If (af.length==0) {
    fcon();
    clearInterval(ai);
    ai = undefined;
  } else {
    i = Math.round( (af.length-1)*Math.random());
    switch(af[i]) {
      case 1:
        a1(); break;
      case 2:
        a2(); break;
      case 3:
        a3(); break;
      default:
        break;
    }
  }
}
var ai = setInterval(“myFunction()”, 1000);

[此答案有一个PDF version,其图形是动态且可交互的。]

【讨论】:

    【解决方案3】:

    我想建议你一些肮脏的东西(:

    var counter=0;
    $.ajax(success:function(){counter++})
    $.ajax(success:function(){counter++})
    $.ajax(success:function(){counter++})
    $.ajax(success:function(){counter++})
    $.ajax(success:function(){counter++})
    
    var interval = setInterval(function(){
     If(counter===5){
       // fire event to elaborate data
       // clear interval
     }
    })
    

    【讨论】:

    • 我想非常强烈建议你不要。
    • 用异步操作做类似++ 的事情是灾难的根源。这通常不是线程安全的,您最终可能会丢失一个增量。
    • @David784 好吧,JS 实际上没有线程,所以在 JS 中这很好,但在现代 JS 中这将是非常糟糕的代码。
    猜你喜欢
    • 2016-02-03
    • 2021-01-30
    • 1970-01-01
    • 2016-03-16
    • 2012-05-04
    • 1970-01-01
    • 2011-10-04
    • 2017-01-22
    • 1970-01-01
    相关资源
    最近更新 更多