reinhard_muc: Parallele AJAX-Aufrufe verarbeiten

Hallo Leute,

ich habe eine js-Funktion geschrieben, die Daten per AJAX aus einer Datenbank holt und damit ein Formular füllt. Jetzt habe ich die Situation, daß ich (fast) gleichzeitig drei Formulare mit Daten füllen will (in einer Baumstruktur sollen bei Klicken auf einen tieferliegenden Knoten auch die übergeordneten Knoten angezeigt werden) und wollte die Funktion 3x hintereinander aufrufen. Dabei gibt es aber Probleme, weil der erste AJAX-Aufruf noch nicht abgearbeitet ist, wenn die nächsten beiden Aufrufe kommen, denn meine bisherige Funktion verarbeitet nur einen Aufruf zugleich.

Ich habe zunächst versucht, aus allen Variablen, die ich für den Aufruf brauche, Arrays zu machen und den Aufrufen eine ID mitzugeben. Das funktioniert aber leider nicht, weil ich meiner Funktion "xmlDatenverarbeitung()", in der der "readystate" abgefragt wird und die ankommenden Daten weitergereicht werden, keinen Parameter mitgeben kann:

Funktion "xmlDatenverarbeitung()" mit
"xmlObjekt.onreadystatechange = xmlDatenverarbeitung" -> funktioniert

Funktion "xmlDatenverarbeitung(Parameter)" mit
xmlObjekt.onreadystatechange = xmlDatenverarbeitung(ID) -> Fehler

Kennt jemand eine andere Methode, verschiedene AJAX-Aufrufe parallel zu verarbeiten? Kann man doch irgendwie einen Parameter mitgeben? Wenn gewünscht, kann ich im nächsten Posting den Quellcode zu meiner fehlerhaften "Lösung" zeigen. Ist aber etwas länger ...

Vielen Dank im Voraus,
Reinhard

  1. ... weil ich meiner Funktion "xmlDatenverarbeitung()", in der der "readystate" abgefragt wird und die ankommenden Daten weitergereicht werden, keinen Parameter mitgeben kann:

    geht doch

    xmlObjekt.onreadystatechange = function () { xmlDatenverarbeitung(ID) };

    1. habe Deine Lösung noch nicht ausprobiert, klingt aber sehr vielversprechend!

      Danke, Reinhard

      xmlObjekt.onreadystatechange = function () { xmlDatenverarbeitung(ID) };

  2. Moin,

    warum 3 ajax-Requests für 3 Ergebnisse wenn die ohnehin fast gleichzeitig sind? Mach _einen_ Ajax-Request und gib 3 Ergebnisse zurück.

    Hotte

    1. Habe ich auch schon dran gedacht. Mir wäre aber eine grundsätzliche Lösung lieber.
      Reinhard

      Moin,

      warum 3 ajax-Requests für 3 Ergebnisse wenn die ohnehin fast gleichzeitig sind? Mach _einen_ Ajax-Request und gib 3 Ergebnisse zurück.

      Hotte

      1. Moin!

        Habe ich auch schon dran gedacht. Mir wäre aber eine grundsätzliche Lösung lieber.

        Das ist jedenfalls die Lösung, die du anstreben solltest.

        Browser senden nur eine begrenzte Zahl von parallelel Requests an den Server, d.h. dein Wunsch nach paralleler Befüllung der Formulare wird gebremst von der eventuell stattfindenden Serialisierung der Requests. Und da jeder einzelne Request eine gewisse Zeit zur Abarbeitung benötigt, wartet dein User insgesamt länger, als er müsste.

        - Sven Rautenberg

        1. Moin!

          »» Habe ich auch schon dran gedacht. Mir wäre aber eine grundsätzliche Lösung lieber.

          Das ist jedenfalls die Lösung, die du anstreben solltest.

          So isses. Es ist auch so, dass viele Serverprozesse ausgelöst von Ajax oder CGI's einen Server ganz schön in die Knie zwingen können. Wenn dann ein einziger Seitenaufruf gleich mehrere Prozesse auf dem Server startet, kann das bei einer gut besuchten Seite schnell mal kritisch werden.

          Hier also liegt der grundsätzliche Ansatz.

          Have a Cigar,
          Hotte

          --
          Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
          1. Hm...

            das mit der begrenzten Anzahl an Server-Prozessen wußte ich nicht, deshalb werde ich die Anregungen von Sven und hotti im Hinterkopf behalten.

            Allerdings:

            • ich programmiere keine allgemeinen Infoseiten für jedermann, sondern eine Webanwendung mit Zugangsbeschränkung für einen begrenzten Personenkreis,
            • mehr als 2 oder 3 gleichzeitige Aufrufe auf einer Seite wird es nicht geben,
            • die übertragenen Datenmengen sind sehr gering (nur alphanumerische Zeichen, keine Grafik o.ä.), allerdings können die dazugehörigen SQL-Abfragen schon komplex sein. Das hat mein Server bisher aber auch schon klaglos ertragen ...

            Trotzdem: wenn eine Funktionalität in Spitzenzeiten von 10 oder 20 Anwendern gleichzeitig (wörtlich) angeklickt wird, könnten leicht 60 oder 70 Aufrufe zusammenkommen.

            Danke für den Tip,
            Reinhard

  3. Nachtrag zum Abschluß des Postings:
    Per Google habe ich aus den weiten des Internets eine sehr schöne Lösung für mein Problem gefunden. Sie wickelt parallele AJAX-calls problemlos nebeneinander ab, ist aber auch für einzelne Calls sehr flexibel. Ich finde es originell, wie die Funktion für die Weiterverarbeitung des Response in den request integriert ist.
    Da der originale Quelltext auf der Community-Seite (wiki.AJAX-Community.de) voller Flüchtigkeitsfehler steckt, hier nochmal der bereinigte Quelltext, der eigentlich funktionieren müßte (zumindest bei mir im IE 7). Dank an den unbekannten Programmierer "narkat".
    ---------------------------------------------

    function request(url, data, type, callback) {  
    	type = type.toUpperCase();  
      
    	// try to create an XHR-Instance  
    	var xhr = false;  
    	if( window.XMLHttpRequest && ! window.ActiveXObject) {  
    		xhr = new XMLHttpRequest();  
    	} else if ( window.ActiveXObject ) {  
    		try {  
    			xhr = new ActiveXObject("Msxml2.XMLHTTP");  
    		} catch(e) {  
    			try {  
    				xhr = new ActiveXObject("Microsoft.XMLHTTP");  
    			} catch(e) {  
    				xhr = false;  
    			}  
    		}  
    	}  
    	if ( ! xhr ) {  
    		throw 'browser not ajax-capable';  
    	}  
      
    	//for GET-Requests append param-string to URL  
    	if ( type == 'GET' ) {  
    		url += '?'+data;  
    	}  
      
    	xhr.onreadystatechange = function() {  
    		if( xhr.readyState == 4 && xhr.status == 200 ) {  
    			callback(xhr);  
    		}  
    	};  
    	xhr.open(type, url, true);  
    	xhr.send( type != 'GET' ? data : null );  
    }
    

    -----------------------------------------
    verwendet wird das ganze dann wie folgt:
    -----------------------------------------

    request('index.php', 'action=foo&bar=123', 'get', function(xhr) {  
    	alert('antwort: '+xhr.responseText);  
    });
    

    Für die callback-Funktion kann man natürlich auch selbstdefinierte Funktionen verwenden. Syntax dann:
    function(xhr){<Funktionsname>(xhr, <ggf. weitere Parameter>)}
    Schöne Grüße,
    Reinhard