Запускать функцию только после завершения нескольких запросов AJAX - PullRequest
6 голосов
/ 04 августа 2010

У меня есть особая функция, которую я хочу запустить один раз и только после завершения нескольких запросов AJAX.

Мое текущее решение выглядит примерно так:

function doWork() {
    //This is the function to be run once after all the requests
}

//some tracking/counting variables
var ajaxDoneCounter = 0;
var numOfAjaxRequests = 5;
var workDone = false;

function doWorkTrigger() {
    ajaxDoneCounter++;
    if( !workDone && ajaxDoneCounter >= numOfAjaxRequests ) {
        workDone = true;
        doWork();
    }
}

// ...

//and a number of ajax requests (some hidden within functions, etc)
//they look something like this:
$.ajax({
    url: "http://www.example.com",
    dataType: "json",
    success: function( data ) {
        //load data in to variables, etc
        doWorkTrigger();
    }
});

Одна из очевидных ошибок в приведенном выше примере заключается в том, что любой неудачный вызов AJAX не будет увеличивать ajaxDoneCount, и поэтому doWork(), вероятно, никогда не будет вызываться. Я могу обойти это, используя обратный вызов error внутри любого $.ajax, так что это меня не слишком беспокоит.

Что я хочу знать, так это то, безопасно ли это и / или является хорошей практикой?
Есть трюк, который я пропустил, или что-то еще, что могло бы работать лучше?

Ответы [ 3 ]

6 голосов
/ 04 августа 2010

Обновление: Начиная с jQuery 1.5, отложенные объекты [документы] обеспечивают более чистое решение. Посмотрите на пример здесь .


Я бы использовал .ajaxComplete(), он будет срабатывать при завершении вызова Ajax (успех или ошибка):

var numOfAjaxRequests = 5;

$(document).ajaxComplete(function() {
    numOfAjaxRequests--;
    if(!numOfAjaxRequests) {
        doWork();

    }
});

Тогда вам не нужно редактировать каждый Ajax-запрос.

Вы даже можете использовать .ajaxSend(), чтобы получать уведомления о запуске Ajax-запросов вместо жесткого его кодирования (но я не уверен, действительно ли это работает, возможно, вы столкнетесь с условиями гонки):

var numOfAjaxRequests = 0;

$(document).ajaxSend(function() {
    numOfAjaxRequests++;
});
1 голос
/ 04 августа 2010

Я думаю, вам следует использовать complete(XMLHttpRequest, textStatus) событие ajax вместо успеха (data, textStatus, XMLHttpRequest).

Согласно справке jQuery:

complete(XMLHttpRequest, textStatus)

Функция, которая вызывается, когда запрос завершается (после успеха и обратные вызовы ошибок выполняются). Функция получает два аргумента: Объект XMLHttpRequest и строка описание состояния запроса. Это Ajax Event.

0 голосов
/ 04 августа 2010

Я не знаю достаточно о внутренностях JavaScript, но есть опасность, что операция:

ajaxDoneCounter++;

не атомарно. Если это так, то это может быть связано с расой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...