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().

Я не уверен, что именно так оно и должно работать, но, похоже, выполняет эту работу.