如何知道所有的ajax调用都已完成

79

我有一个带行的表格样式页面。 每行都有一个复选框。 我可以选择所有/多个复选框,然后单击“提交”,它会为每行进行Jquery ajax调用。

基本上,我为每一行都有一个表单,然后我迭代所有选中的行并提交该表单,该表单执行jquery ajax调用。

所以我有一个按钮,它执行以下操作:

       $("input:checked").parent("form").submit();

然后每一行都有:

            <form name="MyForm<%=i%>" action="javascript:processRow(<%=i%>)" method="post" style="margin:0px;">
                <input type="checkbox" name="X" value="XChecked"/>
                <input type="hidden" id="XNumber<%=i%>" name="X<%=i%>" value="<%=XNumber%>"/>
                <input type="hidden" id="XId<%=i%>" name="XId<%=i%>" value="<%=XNumber%>"/>
                <input type="hidden" id="XAmt<%=i%>" name="XAmt<%=i%>" value="<%=XAmount%>"/>
                <input type="hidden" name="X" value="rXChecked"/>
            </form>

这个表单提交到 processRow 进行处理:

   function processRow(rowNum)
   {
        var Amount = $('#XAmt'+rowNum).val();
        var XId = $('#XId'+rowNum).val();
        var XNum = $('#OrderNumber'+rowNum).val();
        var queryString = "xAmt=" + "1.00" + "&xNumber=" + OrdNum + "&xId=" + xId;


        $('#coda_'+rowNum).removeClass("loader");
        $('#coda_'+rowNum).addClass("loading");


        $.ajax({
          url: "x.asp",
          cache: false,
          type:  "POST",
          data:  queryString,
          success: function(html){
            $('#result_'+rowNum).empty().append(html);
            $('#coda_'+rowNum).removeClass("loading");
            $('#coda_'+rowNum).addClass("loader");
          }
        });
   }
我想知道的是,有没有办法从这里判断我所有的Ajax调用是否都已经完成。原因是希望在这些调用进行时启用/禁用提交按钮。
谢谢,请注意,由于应用程序的敏感性,我不得不篡改变量名,所以其中许多变量可能是重复的。

1
虽然检测所有ajax调用何时完成对于任何设计都有价值,但我认为更好的整体解决方案是一次提交多行。将每行作为单独的ajax post发送在某些方面会对系统造成很大压力,并且不是(在我看来)最佳设计。我甚至可以说,如果您坚持使用每行一个ajax调用的设计,总有一天您会后悔的。 - ErikE
除了@ErikE指出的设计问题之外,我很惊讶没有人提到使用Promises来回答原始问题。 - Delphi.Boy
4个回答

150

简单的方法

最简单的方法是使用.ajaxStop()事件处理程序

$(document).ajaxStop(function() {
  // place code to be executed on completion of last outstanding ajax call here
});

费力的方式

您还可以手动检测是否有任何ajax调用仍在活动:

创建一个包含活动Ajax连接数量的变量:

var activeAjaxConnections = 0;

在打开新的Ajax连接之前,增加该变量。

$.ajax({
  beforeSend: function(xhr) {
    activeAjaxConnections++;
  },
  url (...)

success部分,检查该变量是否等于零(如果是,则最后一个连接已完成)

success: function(html){
  activeAjaxConnections--;
  $('#result_'+rowNum).empty().append(html);
  $('#coda_'+rowNum).removeClass("loading");
  $('#coda_'+rowNum).addClass("loader");
  if (0 == activeAjaxConnections) {
    // this was the last Ajax connection, do the thing
  }
},
error: function(xhr, errDesc, exception) {
  activeAjaxConnections--;
  if (0 == activeAjaxConnections) {
    // this was the last Ajax connection, do the thing
  }
}

正如您所看到的,我还添加了检查返回错误的代码。


4
触发ajaxStop处理程序后,如何再次删除它? - rob
https://dev59.com/KHA65IYBdhLWcg3wogSe - techie_28
3
关于“困难的方式”:无需维护变量,Jquery已经完成了这个工作:$ .active会保持当前活动ajax调用的数量。 - Sebastianb
1
注意:beforesend 应该是 beforeSend。 - Dean
有没有办法在同时进行多个Ajax调用时找出是哪一个? - Si8
"硬编码" - 这是安全的吗?如果多个尝试成功/出错同时在“activeAjaxConnections--;”上操作会怎样? - KunLun

26
一个简洁的解决方案是使用;
$("body").ajaxStop(function() {
    //Your code
});

欲了解更多信息,请查看jQuery .ajaxStop函数,网址为http://api.jquery.com/ajaxStop/


15

-4

直接使用if怎么样?

success: function(html){
   if(html.success == true ){
            $('#result_'+rowNum).empty().append(html);
            $('#coda_'+rowNum).removeClass("loading");
            $('#coda_'+rowNum).addClass("loader");

          }
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接