c--: Auf XMLHTTPRequest-Antwort warten, ohne neue Funktion aufzurufen

Hallo,

ich arbeite mich gerade in Ajax ein.
Bislang schreibe ich meinen Code so, dass eine (Ursprungs-)Funktion, die Daten übertragen will, dafür eine andere Funktion (SendData) aufruft und selbst anschließend abbricht. Die weiteren Befehle, wie zum Beispiel die Ausgabe (Anzeige) der empfangenen Daten, stehen in einer weiteren Funktion (returnfunction), die die Fortsetzung der Ursprungsfunktion darstellt.

Dazu unten ein (bestimmt nicht perfekter) Codeausschnitt.

Ich suche nach einer Möglichkeit, dass die Ursprungsfunktion (DoAction), die ja Daten übertragen und dann anzeigen will, die für die Datenübertragung zuständige Funktion (SendData) aufruft, solange wartet, bis diese fertig ist, und dann im Rückgabewert (von SendData()) schon die Antwort vom Server hat.
Vom Prinzip her also evtl. so:

DoAction(action, input)  
{  
//Daten sammeln  
var dat = "action=" + action + "&input=" + input2 + "&length=" + length2;  
buffer = SendData("cmd.php", dat);  
window.alert("Hi, the server said: " + buffer);  
}

Wie kann ich die Ursprungsfunktion warten lassen, bis die Antwort angekommen ist?

Hier mein bisheriger Code (Ausschnitt):

function SendData(url, params)  
{  
var http = new XMLHttpRequest();  
http.open("POST", url, true);  
  
if (http.overrideMimeType)  
{  
http.overrideMimeType('text/xml; charset=iso-8859-1');  
}  
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");  
http.setRequestHeader("Content-length", params.length);  
http.setRequestHeader("Connection", "close");  
  
http.onreadystatechange = function()  
{  
if (http.readyState == 4 && http.status == 200)  
{  
returncode = http.responseText;  
  
if (returnfunction != "") window.setTimeout(returnfunction, 10);  
returnfunction = "";  
}  
  
}  
  
http.send(params);  
  
//Return code unknown at this point !!  
}  
  
function DoAction(action, input)  
{  
var input2 = escape(input);  
var length2 = input.length;  
var dat = "action=" + action + "&input=" + input2 + "&length=" + length2;  
returnfunction = "DoAction2()";  
SendData("cmd.php", dat);  
  
//Return code unknown at this point  
}  

  1. hi,

    Wie kann ich die Ursprungsfunktion warten lassen, bis die Antwort angekommen ist?

    Dein XHR Objekt sendet einen Request und an diesem XHR Objekt kommt auch die Response an. Das ist wie so ein kleiner Browser im großen Browser. Notiere innerhalb onreadystatechange Deine callback-Funktion, in der die Response in das DOM geschrieben wird. Da geht zum Testen auch schonmal ein alert().

    Hotti

    1. @ChrisB
      Ja, das A steht für asynchronous. Die ganze Sache läuft also asynchron. Das habe ich ja nun auch schon festgestellt.
      Es hätte ja sein können, dass es einen Trick dafür gibt.
      Zum Beispiel eine while-Schleife, die den Browser bzw. die Scriptausführung eben *nicht* lahmlegt...

      @hotti
      Was du schreibst mache ich ja schon längst (erfolgreich). Der Name meiner callback-Funktion wird über die Variable returnfunction übergeben. So kann die Ursprungsfunktion wenigsten flexibel steuern, welche Funktion danach weitermacht. Diese bekommt dann oft den gleichen Namen wie die Ursprungsfunktion, mit einer aufteigenden Zahl hinten dran, damit deutlich erkennbar ist, dass es sich um die Fortsetzungsfunktion handelt.

      Also verstehe ich das richtig, dass es definitv keine Möglichkeit gibt, mein Ziel zu erreichen?

      1. hi,

        Also verstehe ich das richtig, dass es definitv keine Möglichkeit gibt, mein Ziel zu erreichen?

        Was fürn Ziel? Wartet Dein XHR-Objekt etwa nicht auf die Response? Das ist im Protocol so fest geschrieben, dass auf einen Request eine Response erfolgt, wenn Du einen Request rausschickst und würgst dann das XHR-Objekt ab, werden in der Fehlerkonsole eine Reihe von Meldungen angezeigt, das prüf mal bitte.

        Hotti

        1. Was fürn Ziel?

          Mit "Ziel" meinte ich den Wunsch, wie im 1. Post beschrieben, die Ursprungsfunktion auf die Antwort vom Server warten zu lassen, indem SendData() aufgerufen wird, welche die Antwort vom Server als Rückgabewert (return) an die Ursprungsfunktion zurückgibt.
          Ich will wissen, ob ich das asynchrone Verhalten von JavaScript "umgehen" kann.

          1. Hi,

            Mit "Ziel" meinte ich den Wunsch, wie im 1. Post beschrieben, die Ursprungsfunktion auf die Antwort vom Server warten zu lassen, indem SendData() aufgerufen wird, welche die Antwort vom Server als Rückgabewert (return) an die Ursprungsfunktion zurückgibt.
            Ich will wissen, ob ich das asynchrone Verhalten von JavaScript "umgehen" kann.

            Ja natürlich kann man - ich dachte, das hättest du beim Informieren über AJAX inzwischen schon herausgefunden? (Dazu zähle ich auch, sich eine Dokumentation der Parameter des XMLHttpRequest-Objektes mal genauer anzuschauen.)

            Aber *sinnvoll* ist das, glaub's mir bitte, in den allermeisten Fällen aus den schon genannten Gründen *nicht*.

            MfG ChrisB

            --
            The most exciting phrase to hear in science, the one that heralds new discoveries, is not “Eureka!” but “That's funny...” [Isaac Asimov]
          2. Was fürn Ziel?

            Mit "Ziel" meinte ich den Wunsch, wie im 1. Post beschrieben, die Ursprungsfunktion auf die Antwort vom Server warten zu lassen, indem SendData() aufgerufen wird, welche die Antwort vom Server als Rückgabewert (return) an die Ursprungsfunktion zurückgibt.

            Die response, empfangen vom XHR-Object, wird in einer Funktion verarbeitet, die i.A. als callbackfunktion bezeichnet wird. D.h., Du übergibst die response grundsätzlich an die callbackfunktion und hierin ist genau beschrieben, wie die response ggf. geparst und in das DOM eingebaut wird.

            Ich will wissen, ob ich das asynchrone Verhalten von JavaScript "umgehen" kann.

            Asynchron ist relativ zum Browser: Ein ajax-Request geht nach dem Laden einer Seite raus, wenn das DOM und die zum ajax notwendigen Funktione geladen wurden (vorher geht ja nicht). Die ajax Response kommt damit immer später als die dem ajax Request vorausgegangene Response zum Aufbau der Seite. Ansonsten macht Dein xhr-Objekt genau dasselbe auch, was ein Browser macht.

            Hotti

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

              Die response, empfangen vom XHR-Object, wird in einer Funktion verarbeitet, die i.A. als callbackfunktion bezeichnet wird. D.h., Du übergibst die response grundsätzlich an die callbackfunktion [...]

              Nein, das ist nicht grundsätzlich so, denn es gibt ja die synchrone Arbeitsweise, die ohne Callbackfunktionsaufrufe auskommt, weil sie eben auf die Reponse wartet - aber eben den Browser blockiert.

              Ich will wissen, ob ich das asynchrone Verhalten von JavaScript "umgehen" kann.
              Asynchron ist relativ zum Browser: Ein ajax-Request geht nach dem Laden einer Seite raus, wenn das DOM und die zum ajax notwendigen Funktione geladen wurden (vorher geht ja nicht). Die ajax Response kommt damit immer später als die dem ajax Request vorausgegangene Response zum Aufbau der Seite. Ansonsten macht Dein xhr-Objekt genau dasselbe auch, was ein Browser macht.

              Als Antwort wäre ein "Nein" richtig und im Prinzip ausreichend gewesen. Was versuchst du hier mit dem Laden des DOM zu erklären? Der Punkt ist doch bei c-- schon längst Geschichte und nicht relevant. Er weiß grundsätzlich, wie er an die Stelle kommt, an der der Ajax-Request abgesetzt werden kann. Dass Code nicht ausgeführt werden kann, bevor er geladen wurde, ist logisch. Zum Ausführen von JS-Code muss aber nicht der gesamte Seitenaufbau fertig sein, lediglich der JS-Code muss bereits im Browser sein. Und der letzte Satz ist so wie er da steht unsinnig. Abgesehen von dem reinen Request-Response-Handling machen beide eine ganze Menge auf nicht dieselbe Weise.

              Ach Hotti, es ist ja löblich, wenn du versuchst dein Wissen weiterzugeben, aber zu oft kommt da einfach nur Kauderwelsch dabei raus.

              Lo!

              1. moin,

                Ach Hotti, es ist ja löblich, wenn du versuchst dein Wissen weiterzugeben, aber zu oft kommt da einfach nur Kauderwelsch dabei raus.

                Ach ;-)

                Guck doch einfach auf meine Seite, da gibts ajax life und alles funktioniert.

                Schönen Sonntag,
                Horst Haselhuhn

      2. Hi,

        Also verstehe ich das richtig, dass es definitv keine Möglichkeit gibt, mein Ziel zu erreichen?

        Doch - und du hast sie gerade vorher schon grob beschrieben.

        In einem System, dass auf Nutzeraktionen reagieren muss, kannst du nicht immer einfach strikt linear programmieren.
        Gewöhne dich im Gegenteil daran, auf Events zu reagieren - denn gerade beim Gestalten von UI-Logik brauchst du das an jeder Ecke.

        MfG ChrisB

        --
        The most exciting phrase to hear in science, the one that heralds new discoveries, is not “Eureka!” but “That's funny...” [Isaac Asimov]
  2. Hi,

    Wie kann ich die Ursprungsfunktion warten lassen, bis die Antwort angekommen ist?

    Nur, in dem du auf einen synchron Request umstellst - was aber nicht zum empfehlen ist, weil du damit die komplette Seite so lange blockierst.

    Mach dir klar, was das erste A in AJAX wirklich bedeutet - und informiere dich dann, wie man mit den entsprechenden Events den Scriptablauf sinnvoll steuern kann.

    MfG ChrisB

    --
    The most exciting phrase to hear in science, the one that heralds new discoveries, is not “Eureka!” but “That's funny...” [Isaac Asimov]
  3. moin,

    Du könntest Entities erzeugen, Prinzip: der Request kriegt einen entsprechenden Parameter mit und für die Response gibt es einen Tag im header. Auf meiner Seite http://rolfrost.de/cgi-bin/amultirequest.cgi hab ich mal beschrieben, wie sowas gemacht werden kann, allerdings habe ich dazu einfach den ETag missbraucht, was nicht unbedingt empfehlenswert ist, aber es zeigt das Prinzip. Ein eigener Header ist da freilich besser, wenn sowas produktiv werden soll.

    Schönen Sonntag,
    Lokal-Horst