mehrere Requests
Anne-Kathrin Peters
- javascript
0 wahsaga
Hallo liebe Wissende, ;)
ich versuche gerade eine Programmieraufgabe mit Ajax zu lösen. Ich "starte" einen Request um "Computer-Call"-Daten aus einer Datenbank in Form einer Tabelle auszugeben. In der ersten Spalte soll man über einen Klick auf eine Checkbox einen weiteren Request starten können, um die Details anzufordern (diese sind an einer anderen Stelle als die DB gespeichert).
Der Request ist asynchron, d.h. man kann, während der Request abgearbeitet wird, weitere Checkboxen anklicken, um die Details anzufordern. Das heißt, es sollen mehrere Requests losgeschickt werden können.
Diese "Herausforderung" wollte ich mit einer Queue lösen: Bevor ein Request gesendet wird, wird geprüft, ob der "aktuelle" Request fertig abgearbeitet ist, d.h. der Status des aktuellen Requests noch nicht 4 ist (also 1,2, oder 3). Wenn dem so ist, soll die Zieladresse des php-Skripts in einer queue-Variablen gespeichert werden.
Diese queue wird abgearbeitet, sobald der aktuelle Request fertig ist (Status = 4).
Eine Funktion klickt über eine Schleife alle Checkboxen an.
Im Firefox funktioniert das wunderbar. Alle Details werden nacheinander ausgegeben. Nur der Internet Explorer wehrt sich. Er scheint gar keine queue aufzubauen (queue länge über alert ausgegeben: = 0).
Hier mein Code:
queue = new Array(); //wird global erstellt
var detailrequest = new createRequest(); //wird global erstellt
function detailausgabe(callid, checkboxid) ermittelt ob checkbox gecheckt, wenn ja:
var ziel = "detailrequest.php?callid="+callid+"&checkboxid="+checkboxid;
sendDetailRequest(ziel);
function sendDetailRequest(ziel)
{
if(detailrequest)
{
//falls der vorige Request noch nicht abgearbeitet, soll der neue
// Request in eine Warteschlange eingefügt werden:
if(detailrequest.readyState == 1 || detailrequest.readyState == 2
|| detailrequest.readyState == 3)
{
queueLength = queue.length;
queue[queueLength] = ziel;
}
//es wird aktuell kein Request abgeabeitet. Das heißt, es kann
//ein Request initialisiert werden (mit ziel s. Parameter)
else
{
detailrequest.onreadystatechange = updateWithDetails;
detailrequest.open( 'GET', ziel, true );
detailrequest.send( null );
}
}
}
function updateWithDetails()
{
if(detailrequest.readyState==4)
{
if(detailrequest.status == 200)
{
var response = detailrequest.responseText;
makeDetailElement(response); // ergänzt die Detailzeile
}
else
alert("Fehler: Request status is "+detailrequest.status);
//soll das RequestObject aus dem Request Array entfernen
queueLength = queue.length;
if(queueLength > 0)
{
var ersterDetailRequest = queue[0];
//Erstes Element entfernen, den Rest eine Position nach vorne
//rücken
queue.shift();
sendDetailRequest(ersterDetailRequest);
}
}
}
hi,
Der Request ist asynchron, d.h. man kann, während der Request abgearbeitet wird, weitere Checkboxen anklicken, um die Details anzufordern. Das heißt, es sollen mehrere Requests losgeschickt werden können.
Diese "Herausforderung" wollte ich mit einer Queue lösen: Bevor ein Request gesendet wird, wird geprüft, ob der "aktuelle" Request fertig abgearbeitet ist, d.h. der Status des aktuellen Requests noch nicht 4 ist (also 1,2, oder 3). Wenn dem so ist, soll die Zieladresse des php-Skripts in einer queue-Variablen gespeichert werden.
Diese queue wird abgearbeitet, sobald der aktuelle Request fertig ist (Status = 4).
Also erzeugst du doch wieder Synchronität - warum setzt du dann nicht gleich die Requests synchron ab?
Im Firefox funktioniert das wunderbar. Alle Details werden nacheinander ausgegeben. Nur der Internet Explorer wehrt sich. Er scheint gar keine queue aufzubauen (queue länge über alert ausgegeben: = 0).
Dann überprüfe doch erst mal, ob er die Stelle, wo er einen neuen Request "queuen" soll, überhaupt reicht.
Tipp: Zum einfacheren Testen würde ich die Beantwortung der Requests ggf. serverseitig verzögern, durch ein sleep() o.ä.
gruß,
wahsaga
Hey Wahsaga,
vielen Dank für deine Antwort. :)
Diese queue wird abgearbeitet, sobald der aktuelle Request fertig ist (Status = 4).
Also erzeugst du doch wieder Synchronität - warum setzt du dann nicht gleich die Requests synchron ab?
Meinst du wirklich? Ich warte doch nicht auf die Antwort des Servers. Während der Request abgearbeitet wird, soll er weitere "Checkboxklicks" aufnehmen und in einer queue speichern!? Dann ist es doch asynchron, oder? Es wird halt nur ein Request Object benutzt. Mmmhhh... Wie kann ich denn dynamisch mehrere Requestobjects "nebeneinander" erzeugen, ohne, dass er durcheinander kommt?
Im Firefox funktioniert das wunderbar. Alle Details werden nacheinander ausgegeben. Nur der Internet Explorer wehrt sich. Er scheint gar keine queue aufzubauen (queue länge über alert ausgegeben: = 0).
Dann überprüfe doch erst mal, ob er die Stelle, wo er einen neuen Request "queuen" soll, überhaupt reicht.
Ja, er erreicht sie. Manchmal. Ich verstehe nicht: der erste Request wird korrekt abgearbeitet. Dann startet er gleich den 2. Request (ohne ihn in die queue zu schreiben) und obwohl das Ergebnis nie erscheint baut er dann manchmal ne queue auf (bei 22 Einträgen war ich am Ende bei queuelänge=8), manchmal schießt er den request, einfach los- obwohl das Ergebnis des aktuellen Requests noch nicht da ist. Am Ende baut er die queue aber auch nicht wieder ab.
Beim Firefox wird der erste Request gestartet und dann mit den restlichen Checkbox-Zieladressen (Php-Skript & Parameter) die queue aufgebaut. Wenn der erste Request dann fertig ist, arbeitet er systematisch die Queue ab. Genau so, wie ich's haben wollte.
*Mmmpf*
Vielleicht fällt dir / euch ja noch etwas ein!?
Liebe Grüße,
Anne
Tipp: Zum einfacheren Testen würde ich die Beantwortung der Requests ggf. serverseitig verzögern, durch ein sleep() o.ä.
gruß,
wahsaga
Hallo ihr,
Es ist gelöst :))) *jippie*
Der Haken bestand scheinbar darin, dass er mit jeder neuen Anfrage das "gerade fertige Requestobjekt" aufgerufen hat um damit einen neuen Request zu starten. Ich habe das Request Object einfach nochmal neu initialisiert.
detailrequest = new createRequest();
so geht's dann in den nächsten Zeilen weiter:
detailrequest.onreadystatechange = updateWithDetails; detailrequest.open( 'GET', ziel, true );
detailrequest.send( null );
Ein weiteres Problem war die queue. Ich hatte sie wie folgt aufgebaut:
queueLength = queue.length;
queue[queueLength] = ziel; //ziel = php-url?parameter
var ersterDetailRequest = queue[0]; brachte manchmal einen wert "undefined" hervor.
Jetzt baue ich die queue wie folgt auf: "queue.push(ziel);"
Alles funzt so, wie es geplant war :)