2012-03-26 15 views
30

Ich habe ein Problem mit jQuery.when() zu warten, bis mehrere AJAX-Anforderungen vor dem Aufruf einer anderen Funktion zu beenden.jQuery .wenn Fehlersuche mit variabler Anzahl von Argumenten

Jeder Ajax-Request wird JSON-Daten erhalten, und sieht ungefähr so ​​aus:

function loadData(arg){ 
     var ajaxCall = $.ajax(
      URL // depends on arg 
     ) 
     .error(....); 
     return ajaxCall; 
    } 

Wenn die Anforderung aufgerufen wird, wird der Rückgabewert (ajaxCall) zu einer Liste hinzugefügt ajaxRequests genannt. abzuschließen

ajaxRequests = []; 
    ajaxREquests.push(loadData(arg)) 

Wenn alle Anfragen gemacht wurden, ich versuche ajaxRequests zu $ ​​.when, um für alle Anforderungen zu warten, zu übergeben.

 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 ist ein Objekt, das Diagramme basierend auf JSON-Daten lädt und zeichnet.

Das Problem ist, dass es scheint nicht zu warten, bis die Anforderungen zu beenden - args [i] ist ein Objekt, aber responseText ist nicht definiert, wenn der Code ausgeführt wird. Wenn ich args [i] speichere und später auf die Konsole zugreife, funktioniert es.

Ich vermute, dass das Problem mit der Verwendung von .when mit einer beliebigen Anzahl von Argumenten verbunden ist, wie alle Beispiele, die ich im Web gesehen habe, geben Sie eine vordefinierte Argumentliste.

Ich bin mir nicht sicher, ob die Verwendung von apply die richtige Idee war oder nicht, aber so oder so funktioniert es nicht richtig und verhält sich unregelmäßig (Browser-abhängig).

Jeder würde Hilfe sehr geschätzt.

Bitte lassen Sie mich wissen, wenn weitere Informationen benötigt werden.
Ich benutze jQuery 1.5

+1

Vielleicht ist es nur mich, aber die Syntax, die Sie in Ihrem Code haben scheint nicht, dass aus dem jQuery API anzupassen (http: //api.jquery. com/jQuery.when /). Vielleicht möchten Sie diese Syntax ausprobieren und sehen, ob sie funktioniert? – fayerth

+0

Ich glaube, sein Punkt war, dass er es nicht so benutzt, wie es in den Dokumenten angezeigt wird, weil er eine variable Anzahl von Argumenten hat. –

+0

@genau genau. – Alex

Antwort

32

Obwohl Alex tatsächlich eine Lösung für sein Problem bot, fand ich es ein bisschen schwierig. Ich hatte ein ähnliches Problem wie ich, und ich wollte meine Lösung für alle anderen freigeben, die eine variable Anzahl von Ajax-Anfragen verarbeiten müssen.

// 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 
    }); 

}); 
+0

Danke Andy! Arbeitete für mich. – aldux

+0

Danke für die Zuschreibung Andy :) das ist viel klarer – Alex

+3

Dank Andy, es funktioniert großartig, solange alle Anfragen erfolgreich sind, aber wie geht es Ihnen, wenn man erfolgreich ist und man scheitert? –

4

Ich glaube, ich es jetzt gearbeitet habe aus - das Problem war die zurückgegebenen Argumente bei der Verarbeitung. .done erhielt nur drei Argumente - den Antworttext, den Status und das jqXHR-Objekt. Ich habe erwartet, dass es das jqXHR-Objekt, das aus jeder Abfrage resultiert, passiert.

Ich habe es gelöst, indem ich den Callback-Code für jede Abfrage in eine separate Funktion verschoben habe (dh der Ajax-Aufruf in loadData spezifiziert jetzt eine Callback-Funktion, die den Aufruf '.loadData (...)' ausführt) Das einzige, was mit dem .done-Aufruf erledigt wird, ist die inst.draw(). Dies scheint gut zu funktionieren: die einzelnen Callbacks werden jeweils vor .done() ausgeführt.

Ich bin mir nicht sicher, ob es genau so funktioniert, aber es scheint den Job zu machen.

9

Neben Andy Corman Antwort (ich noch nicht in der Lage bin auf einen Beitrag zu antworten, ich glaube, ...), wenn Sie nur eine Anfrage haben, wird die Antwortinformation direkt an den Zurückstellungs weitergegeben werden.getan - Funktion als Argument; Sie müssen also eine geben, wenn für diesen Fall:

// 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 
     }); 
}); 
+0

Funktioniert nicht mehr mit v1.11.3. Done() wird ausgelöst, sobald alle Anfragen ausgegeben wurden. –

Verwandte Themen