Як дізнатися, коли всі виклики ajax завершені


75

У мене є сторінка стилю таблиці з рядками. Кожен рядок має прапорець. Я можу встановити всі / багато прапорців і натиснути "надіслати", а що робить, це виклик 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-call-per-row, ви пошкодуєте.
ErikE

Окрім проблеми дизайну, на яку вказав @ErikE, я здивований, що ніхто не згадував використання Promises для відповіді на вихідне питання.
Дельфи. Хлопець

Відповіді:


139

Простий спосіб

Найпростіший спосіб - використовувати .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 після його запуску?
грабувати


3
Щодо "Жорсткого шляху": Не потрібно підтримувати змінну, Jquery вже робить це: $ .active зберігає поточну кількість активних викликів ajax
Sebastianb

1
Примітка beforesend повинна бути beforeSend
Дін

Чи є спосіб зрозуміти, яким це був Ajax, якщо їх було кілька одночасно?
Si8



-4

Як щодо просто використовувати if ?

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

          }
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.