5 Stimmen

Wie man wartet, bis verschachtelte asynchrone jQuery AJAX-Anfragen abgeschlossen sind?

Ich benutze jQuery und habe eine Schleife von asynchronen AJAX-Anfragen. Ich weiß, dass ich auf sie alle warten kann, bis sie fertig sind, indem ich die praktische Methode '$.when.apply(array_of_requests).then()' benutze.

Aber ich habe auch eine weitere Gruppe von AJAX-Anfragen, die nur ausgeführt werden, nachdem jede der ersten Anfragen abgeschlossen ist. Ich möchte auch auf sie warten, bin mir aber nicht zu 100% sicher, ob ich den besten Weg gefunden habe.

Hier ist ein vereinfachtes Beispiel meiner Anfragen:

var intital_data = [1,2,3,4,5,6,7,8,9,10];
var promises = [];
var promises_inner = [];

$.each(intitial_data, function(i, n) {
    var ajax_call = $.ajax({url:'http://www.domain.com/etc/'+n});
    promises.push(ajax_call);

    ajax_call.done(function(data) {
        var ajax_call_inner = $.ajax({url:'http://www.domain.com/etc/'+data.result});
        promises_inner.push(ajax_call_inner);

        ajax_call_inner.done(function(data) {
            // Hier wird etwas mit dem Inhalt von data gemacht.
        });
    });
});

Also, wenn jede der zehn durchgeführten AJAX-Anfragen abgeschlossen ist, mache ich eine zweite AJAX-Anfrage basierend auf den Ergebnissen der ersten. Das funktioniert alles gut.

Dann habe ich etwas wie das hier, weil ich warten möchte, bis sowohl die ersten zehn Anfragen (gespeichert im promises-Array) als auch die zweite Gruppe (gespeichert in promises_inner) abgeschlossen sind:

$.when.apply($, promises).then(
    function() {
        // Die zehn äußeren AJAX-Aufrufe sind jetzt abgeschlossen.

        $.when.apply($, promises_inner).then(
            function() {
                // Die inneren AJAX-Aufrufe sind jetzt abgeschlossen.
            }
        );
    }
);

Innerhalb der 'done'-Funktion des ersten $.when.apply().then() sind die zweiten Anfragen noch nicht abgeschlossen oder sogar dem promises_inner-Array hinzugefügt worden. Aber ich fand heraus, dass das Hinzufügen einer verschachtelten $.when.apply().then() zu funktionieren scheint - innerhalb seiner 'done'-Funktion sind alle Anfragen abgeschlossen.

Aber ich bin mir nicht sicher, ob das die beste und zuverlässigste Lösung ist. Ich mache mir Sorgen, dass es nur zufällig funktioniert - dass es gerade genug Verzögerung verursacht, damit die Aufrufe abgeschlossen sind - anstatt logischen Sinn zu ergeben.

Gibt es eine bessere, robuster Lösung? Danke.

2voto

AutoSponge Punkte 1446

Werfen Sie einen Blick auf $.Callbacks in 1.7. Ich glaube, Sie werden von der Flexibilität begeistert sein, Ihre eigenen "Flows" zu erstellen und die Möglichkeit, sie wiederzuverwenden, einmal auszuführen usw.

An dem, was Sie gemacht haben, ist nichts falsch (das Anwendungsmuster ist möglicherweise nicht die erste Wahl der meisten, sie listen sie normalerweise nur in einem $.when(a, b, c....) auf - aber Ihnen könnte die Syntax von $.Callbacks besser gefallen.

0voto

Squ1sh Punkte 27

Versuchen Sie dies nur mit einem Hauptversprechen pro Schleifendurchlauf zu erfüllen (auflösen) (hier immer noch als inner_promise bezeichnet).

var initial_data = [1,2,3,4,5,6,7,8,9,10];
var promises_inner = [];

initial_data.forEach(function(n) {
    // Versprechen für den inneren Aufruf hier erstellen.
    var promise_inner = $.Deferred();
    promises_inner.push(promise_inner);

    $.ajax({url:'http://www.domain.com/etc/'+n}).done(function(data) {
        $.ajax({url:'http://www.domain.com/etc/'+data.result}).done(function(data) {
            // Hier etwas mit dem Inhalt von data machen.
            promise_inner.resolve();
        });
    });
});
console.log("promises_inner enthält " + promises_inner.length + " Versprechen") // sollte alle 10 Versprechen enthalten

$.when.apply($,promises_inner).done(function() {
    // Die inneren AJAX-Aufrufe sind jetzt abgeschlossen
})

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X