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 не определен при выполнении кода. Если я сохраню args [i] и получу к нему доступ позже из консоли, это сработает.

Я подозреваю, что проблема связана с использованием.when с произвольным числом аргументов, поскольку все примеры, которые я видел в Интернете, дают ему заранее определенный список аргументов.

Я не уверен, что использование apply было правильной идеей или нет, но в любом случае это не работает должным образом и ведет себя хаотично (зависит от браузера).

Любая помощь будет принята с благодарностью.

Пожалуйста, дайте мне знать, если требуется дополнительная информация.
Я использую jQuery 1.5

4 ответа

Решение

Хотя Алекс действительно обеспечил решение своей проблемы, мне было немного трудно следовать ей. У меня была проблема, похожая на его, которую я решил, и я хотел поделиться своим решением для всех, кому нужно обрабатывать переменное число запросов 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
    });

});

В дополнение к ответу Энди Кормана (я все еще не могу ответить на сообщение, я думаю...), если у вас есть только один запрос, информация об ответе будет передана непосредственно в 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
        });
});

Я думаю, что я решил это сейчас - проблема была в обработке возвращенных аргументов..done получал только три аргумента - текст ответа, статус и объект jqXHR. Я ожидал, что он получит объект jqXHR, полученный в результате каждого запроса.

Я решил это, переместив код обратного вызова для каждого запроса в отдельную функцию (то есть вызов ajax в loadData теперь определяет функцию обратного вызова, которая выполняет вызов '.loadData(...)'), и единственное, что делается вызовом.done является inst.draw(). Кажется, это работает нормально: каждый отдельный обратный вызов выполняется перед.done().

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

Попробуйте ajaxStart и ajaxStop, у которых есть слушатели для открытых запросов ajax.

http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/

Другие вопросы по тегам