JQuery. После устранения неполадок с переменным числом аргументов
У меня возникла проблема с использованием jQuery.when() для ожидания завершения нескольких запросов ajax до вызова другой функции.
Каждый запрос ajax получит данные JSON и выглядит примерно так:
function loadData(arg){
var ajaxCall = $.ajax(
URL // depends on arg
)
.error( .... );
return ajaxCall;
}
Когда запрос вызывается, возвращаемое значение (ajaxCall) добавляется в список, называемый ajaxRequests.
ajaxRequests = [];
ajaxREquests.push(loadData(arg))
Когда все запросы были сделаны, я пытаюсь передать ajaxRequests в $.when, чтобы ждать завершения всех запросов.
var defer = $.when.apply($, ajaxRequests);
defer.done(function(args){
for (var i=0; i<args.length; i++){
inst.loadData($.parseJSON(args[i].responseText));
}
inst.draw();
});
inst - объект, который загружает и рисует графики на основе данных JSON.
Проблема в том, что, похоже, на самом деле не ждет завершения запросов - args [i] - это объект, а responseText - undefined при запуске кода. Если я сохраню args [i] и позже его получаю с консоли, он будет работать.
Я подозреваю, что проблема связана с использованием .when с произвольным количеством аргументов, так как все примеры, которые я видел в Интернете, дают ему предварительно определенный список аргументов.
Я не уверен, что использование приложения было правильной идеей или нет, но в любом случае она не работает должным образом и ведет себя беспорядочно (зависит от браузера).
Любая помощь будет принята с благодарностью.
Пожалуйста, дайте мне знать, если требуется дополнительная информация.
Я использую jQuery 1.5
Ответы
Ответ 1
Хотя Алекс действительно обеспечил решение своей проблемы, я обнаружил, что это немного сложно. У меня была проблема, сходная с его тем, что я решил, и я хотел поделиться своим решением для всех, кто должен обрабатывать переменное количество запросов ajax.
// Array of requests
var requests = Array();
requests.push($.get('responsePage.php?data=foo'));
requests.push($.get('responsePage.php?data=bar'));
var defer = $.when.apply($, requests);
defer.done(function(){
// This is executed only after every ajax request has been completed
$.each(arguments, function(index, responseData){
// "responseData" will contain an array of response information for each specific request
});
});
Ответ 2
В дополнение к ответам Энди Кормана (я еще не могу ответить на сообщение, я думаю...), если у вас есть только один запрос, информация ответа будет передана непосредственно функции defer.done как аргумент; Поэтому вам нужно указать if для этого случая:
// Array of requests
var requests = Array();
requests.push($.get('responsePage.php?data=foo'));
var defer = $.when.apply($, requests);
defer.done(function(){
// This is executed only after every ajax request has been completed
if (requests.length == 1)
// "arguments" will be the array of response information for the request
else
$.each(arguments, function(index, responseData){
// "responseData" will contain an array of response information for each specific request
});
});
Ответ 3
Я думаю, что сейчас я это обработал - проблема заключалась в обработке возвращаемых аргументов..done получал только три аргумента - текст ответа, статус и объект jqXHR. Я ожидал, что он получит объект jqXHR, полученный в результате каждого запроса.
Я решил это, переместив код обратного вызова для каждого запроса на отдельную функцию (т.е. вызов ajax в loadData теперь указывает функцию обратного вызова, которая вызывает вызов ".loadData(...)" ) и единственная Вещь, выполняемая вызовом .done, - inst.draw(). Кажется, это работает нормально: каждый обратный вызов выполняется каждый раз перед .done().
Я не уверен, что именно так оно и должно работать, но, похоже, выполняет эту работу.
Ответ 4
Попробуйте ajaxStart и ajaxStop, у которых есть слушатели для открытых запросов ajax.
http://api.jquery.com/ajaxStart/
http://api.jquery.com/ajaxStop/