Ajax-Anfragen queuen
Problem
Sie brauchen eine bessere Kontrolle über die Reihenfolge der vielen unterschiedlichen Ajax-Anfragen.
Lösung
Dieses Rezept stellt zwei verschiedene Wege vor, wie man Ajax-Anfragen queuen kann. Der erste füllt eine Queue mit Anfragen, die dann nacheinander abgesendet werden. Dabei wird die nächste Anfrage immer erst abgeschickt, wenn die Antwort der ersten Anfrage zurückgekommen ist. Der zweite schickt immer eine Gruppe von Anfragen parallel ab. Aber die Callback-Funktionen für jede Anfrage werden immer erst dann ausgeführt, wenn alle Antworten zurückgekommen sind. Zum Vergleich hier ein Beispiel für normale, nicht gequeuete Anfragen:
<!DOCTYPE html> <html><head> <title>jQuery-Kochbuch - 17.5 - Ajax-Anfragen queuen</title> <script type="text/javascript" src="jquery-1.3.2.min.js"></script> <script type="text/javascript" src="jquery-ajax-queue_1.0.js"></script> </head> <body> <h1>17.5 - Ajax-Anfragen queuen</h1> <input type="button" id="unqueued-requests" value="Nicht gequeuete Anfragen"></input> <input type="button" id="queued-requests" value="Gequeuete Anfragen"></input> <input type="button" id="synced-requests" value="Synchronisierte Anfragen"></input> <p id="response"></p> </body></html>
Das jQuery-Plugin ajaxqueue (verfügbar unter http://plugins.jquery.com/project/ajaxqueue/) wird genutzt, um das Queueing zu ermöglichen. Drei verschiedene Buttons lösen jeweils eine Gruppe von Ajax-Anfragen aus. In einem Absatz-Element zeigen wir ein Protokoll mit den Antworten an:
(function($) { $('document').ready(function() { $('#unqueued-requests').click(function() { $('#response').empty(); $.each([1,2,3,4,5,6,7,8,9,10], function() { $.get('server.php',{ data: this }, function(data) { $('#response').append(data); }); }); return false; });
Der erste Button löst ganz normale
Ajax-Anfragen aus. Es werden zehn Anfragen abgeschickt, wobei jede
die Position in der Liste mitschickt. Das Skript server.php
simuliert einen Server unter Last,
indem er eine zufällige Zeitspanne abwartet, bevor er eine Antwort
zurücksendet. Kommt diese an, wird die Anwort an den Inhalt des
Absatzes #response
angehängt.
$('#queued-requests').click(function() { $('#response').empty(); $.each([1,2,3,4,5,6,7,8,9,10], function() { $.ajaxQueue({url: 'server.php', data: { data: this }, success: function(data) { $('#response').append(data); } }); }); $.dequeue( $.ajaxQueue, "ajax" ); return false; });
Der Button »Gequeuete Anfragen« trägt jede
Anfrage in eine Queue ein, indem er die Funktion ajaxQueue()
aufruft. Intern wird die Funktion ajax()
mit den angegebenen Optionen aufgerufen,
wenn eine Anfrage aus der Queue geholt wird. Nachdem alle Anfragen
eingetragen wurden, löst ein Aufruf von dequeue()
mit der Funktion ajaxQueue
als Parameter die erste Anfrage aus.
Alle folgenden Anfragen werden anschließend abgearbeitet.
$('#synced-requests').click(function() { $('#response').empty(); $.each([1,2,3,4,5,6,7,8,9,10], function() { $.ajaxSync({url: 'server.php', data: { data: this }, success: function(data) { $('#response').append(data); } }); }); return false; }); }); })(jQuery);
Die letzte Gruppe von Anfragen nutzt die
Funktion ajaxSync()
, um die Anfragen parallel
abzuschicken. Die angegebenen Callbacks werden aber synchronisiert,
wenn die Antworten wieder eintreffen.
Diskussion
Antworten von den nicht gequeueten Anfragen
kommen in einer nicht vorhersagbaren Reihenfolge zurück. Dieses
Verhalten muss nicht unbedingt unerwünscht sein – in vielen Fällen
ist es sogar zu bevorzugen. Aber es gibt Szenarien, in denen man
mehr Kontrolle über die Ajax-Anfragen und -Antworten haben möchte.
Die von ajaxQueue()
bereitgestellte
Funktionalität ist dann sinnvoll, wenn jede Anfrage von der Antwort
der vorherigen Anfrage abhängt, während ajaxSync()
dafür genutzt werden kann, Daten zu
verändern, die von verschiedenen Servern geholt werden müssen.
Dabei kann mit der Verarbeitung erst begonnen werden, wenn alle
Server eine Antwort geliefert haben und alle Daten vorhanden
sind.