Дождитесь завершения вызова AJAX (POST) - PullRequest
9 голосов
/ 15 сентября 2010

Я использую вкладки пользовательского интерфейса jQuery, где каждая вкладка имеет свою форму.После того, как пользователь вводит различные фрагменты данных, он отправляет весь набор вкладок, так что каждая вкладка отправляет на сервер асинхронно.Это хорошо работает, и у меня нет проблем здесь.

Однако, где я сталкиваюсь с проблемой, это то, что последняя форма, которую я отправляю, должна появиться ПОСЛЕ всех остальных сообщений.Общая идея такова:

postForm(0, "#Form1");
postForm(1, "#Form2");
postForm(2, "#Form3");
postForm(3, "#Form4");
$.post('Project/SaveProject', function (data) {
    $('<div class="save-alert">The current project has been saved.</div>')
    .insertAfter($('#tabs'))
    .fadeIn('slow')
    .animate({ opacity: 1.0 }, 3000)
    .fadeOut('slow', function () {
        $(this).remove();
    });
});

Функция postForm выполняет небольшую обработку, а затем выполняет вызов AJAX $ .post.Последний выполненный здесь $ .post (для 'Project / SaveProject') должен дождаться завершения этих постов.Каков наилучший способ сделать это?

Ответы [ 4 ]

15 голосов
/ 15 сентября 2010

Вы можете просто использовать событие .ajaxStop(), которое срабатывает, когда заканчиваются все остальные AJAX POST, при условии, что вы не выполняете никакой другой работы AJAX, например:

postForm(0, "#Form1");
postForm(1, "#Form2");
postForm(2, "#Form3");
postForm(3, "#Form4");
$(document).ajaxStop(function() {
  $.post('Project/SaveProject', function (data) {
    $('<div class="save-alert">The current project has been saved.</div>')
    .insertAfter($('#tabs'))
    .fadeIn('slow')
    .animate({ opacity: 1.0 }, 3000)
    .fadeOut('slow', function () {
      $(this).remove();
    });
  });
  $(this).unbind('ajaxStop');
});

.ajaxStop() срабатывает, когда все AJAX-запросы, которые выполняются, поэтому он будет срабатывать только при возврате всех из этих POST, jQuery сохраняет внутренний счет ($.active, $.ajax.active в jQuery 1.5) для определения количества ожидающих одновременных запросов AJAX ... когда он возвращается к 0, это событие запускается.

Этот подход позволяет одновременно выполнять другие отправки форм и делать окончательную форму как можно скорее.

5 голосов
/ 23 сентября 2010

Вы всегда можете сделать все сообщения синхронными, используя что-то вроде


$.ajax({
   type: "POST",     
   async: false,
   url: "",
   ...

конечно, это будет не так быстро, но это решит вашу проблему, если $ (document) .ajaxStop не является опцией

2 голосов
/ 15 сентября 2010

Callbacks:

Определите postForm для обратного вызова:

function postForm(ind, id, callback)
{
  // ...
  $.post(url, function()
  {
    // ...
    callback();
  });
}

Тогда сделайте что-то вроде ниже. Вы можете использовать рекурсию, чтобы написать ее менее жестко, что может быть особенно полезно, если есть больше форм.

postForm(0, "#Form1", function()
{
    postForm(1, "#Form2", function()
    { 
        postForm(2, "#Form3", function()
        {
            postForm(3, "#Form4", function()
            {
                $.post('Project/SaveProject', function (data) {
                    $('<div class="save-alert">The current project has been saved.</div>')
                        .insertAfter($('#tabs'))
                        .fadeIn('slow')
                        .animate({ opacity: 1.0 }, 3000)
                        .fadeOut('slow', function () {
                            $(this).remove();
                        });
                });
            });
        });
    });
});
0 голосов
/ 15 сентября 2010

Проблема с ajaxStop заключается в том, что он будет запускаться каждый раз, когда выполняется любой ajax. Альтернативой является реализация вашего собственного стека методов следующим образом:

var stack = []
postForm(var1, var2){
    stack.push(1);
    //Do postForm stuff
    stack.pop();
    if (stack == undefined){
        //Call the last post method
    }
}
postForm(0, "#Form1");
postForm(1, "#Form2");
postForm(2, "#Form3");
postForm(3, "#Form4");
$.post('Project/SaveProject', function (data) {
    $('<div class="save-alert">The current project has been saved.</div>')
    .insertAfter($('#tabs'))
    .fadeIn('slow')
    .animate({ opacity: 1.0 }, 3000)
    .fadeOut('slow', function () {
        $(this).remove();
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...