Felix unreg: Zwei parallele Ajax-Requests

Guten Morgen!

Ich sitz gerade an folgendem Problem: ich möchte vor dem Absenden eines Formulars das Formular mittels Ajax überprüfen. Dafür muss ich zwei Ajax-Requests senden. Da der Server aber für die Antwort seinerseits (teilweise relativ langsame) Webservices ansprechen muss würde ich diese beiden Request gerne parallel absenden. Da ich aber warten muss, bis diese beiden Requests abgesendet sind, um zu sagen, ob die Formulareingaben so gültig sind, kann ich diese nicht einfach asynchron laufen lassen. Also ein Beispiel verdeutlicht mein Problem denk ich am Besten.

(...)
<form (...) onsubmit="return form_submit()">
(...)

Die Requests nacheinander zu senden dürfte kein Problem darstellen (so in der Art):

  
function form_submit(){  
  var ajaxcheck = false;  
  Ajax.Request(  
    "/ajax1",  
    {  
      method: 'get',  
      parameters: '',  
      asynchronous: false,  
      onComplete: function(e){  
        // überprüfe Antwort, ggf setze ajaxcheck auf true  
        ajaxcheck = true;  
    }  
  );  
  if (!ajaxcheck)  
    return false;  
  ajaxcheck = false;  
  Ajax.Request(  
    "/ajax2",  
    {  
      method: 'get',  
      parameters: '',  
      asynchronous: false,  
      onComplete: function(e){  
        // überprüfe Antwort, ggf setze ajaxcheck auf true  
        ajaxcheck = true;  
    }  
  );  
  return ajaxcheck;  
}  

Um diese Requests parallel laufen zu lassen bräuchte ich soetwas.

  
function form_submit(){  
  ajaxcheck = 1;  
  Ajax.Request(  
    "/ajax1",  
    {  
      method: 'get',  
      parameters: '',  
      asynchronous: true,  
      onComplete: function(e){  
        // überprüfe Antwort und schreib Ergebnis in is_valid  
        var is_valid;// true oder false  
        ajaxcheck *= is_valid ? 3 : 2;  
    }  
  );  
  Ajax.Request(  
    "/ajax2",  
    {  
      method: 'get',  
      parameters: '',  
      asynchronous: true,  
      onComplete: function(e){  
        // überprüfe Antwort und schreib Ergebnis in is_valid  
        var is_valid;// true oder false  
        ajaxcheck *= is_valid ? 3 : 2;  
    }  
  );  
  // Diese Stelle ist ungünstig  
  while (ajaxcheck < 4);  
  return (ajaxcheck == 9);  
}  

Diese Lösung kann ich in der Praxis natürlich nicht so verwenden. Hat jemand einen besseren Vorschlag? Zur Not müsste ich beide Checks in einen Request verpacken und den dann synchron abschicken, ist aber in meinem Fall ein wenig unelegant.

Gruß,
Felix

  1. hi,

    [..] Zur Not müsste ich beide Checks in einen Request verpacken und den dann synchron abschicken, ist aber in meinem Fall ein wenig unelegant.

    Genau das würde ich machen: Ein Request => eine Response. Bei zwei Requests wirds nämlich schwierig, die Responsen auseinanderzuhalten.

    Hotte

    1. [..] Zur Not müsste ich beide Checks in einen Request verpacken und den dann synchron abschicken, ist aber in meinem Fall ein wenig unelegant.

      Genau das würde ich machen: Ein Request => eine Response.

      Genau das möchte er machen, aber diese laufen parallel, genau das ist ein Merkaml von Ajax.

      Bei zwei Requests wirds nämlich schwierig, die Responsen auseinanderzuhalten.

      Inwiefern das?

      Struppi.

    2. Hi,

      [..] Zur Not müsste ich beide Checks in einen Request verpacken und den dann synchron abschicken, ist aber in meinem Fall ein wenig unelegant.

      Genau das würde ich machen: Ein Request => eine Response. Bei zwei Requests wirds nämlich schwierig, die Responsen auseinanderzuhalten.

      Grundsätzlich hast du recht, aber ich hab grad gemerkt dass es _in meinem Fall_ nicht nur unelegant, sondern am Ende gar keine große Performanceverbesserung ist.

      Weil:

      Es geht bei mir um Adressenvalidierung. Ich übergebe dem Webservice eine Adresse und er macht Vorschläge (z.B. Mustrestraße => Musterstr, Masterstr), die ich dann dem User anbiete. Ich kann dem WS aber leider nur immer _eine_ Adresse übergeben. Auf dem Server läuft PHP. Das heißt auch wenn ich _beide_ Adressen in _einem_ Ajax-Request verpacke müsste am Ende der Server die zeitraubenden SOAP-Requests _nacheinander_ ausführen. Ich spare also nicht viel.

      Gruß,
      Felix

  2. Lieber Felix,

    betrachte Ajax-Requests grundsätzlich wie setTimeout-Aufrufe. Du weißt nie, wann sich da was tut.

    Deswegen solltest Du nicht einfach davon ausgehen, dass Du innerhalb einer Funktion einfach eine Variable definieren kannst, die am Ende der Funktion nach zwei Ajax-Calls einen Wert hat, der dann zurückgegeben werden kann.

    Meiner Meinung nach solltest Du zwei Funktionen benutzen. Die erste ist eine Callback-Funktion, die von den beiden Ajax-Calls mit dem jeweiligen Ergebnis (auch wenn der Call an sich scheitert!) "gefüttert" wird, um dann zu prüfen, ob der gerade eingegangene Ajax-Call bereits der zweite eingetroffene war. In diesem Fall kann diese erste Funktion nämlich die zweite Funktion aufrufen, die das Formular abschickt, oder eben zurückweist.

    Der Usability wegen würde ich eine Anzeige einblenden, die dem Benutzer klarmacht, dass da gerade eine Prüfung stattfindet, und das er sich gedulden muss.

    Was machst Du, wenn kein JavaScript verfügbar ist?

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Lieber Felix,

      Der Usability wegen würde ich eine Anzeige einblenden, die dem Benutzer klarmacht, dass da gerade eine Prüfung stattfindet, und das er sich gedulden muss.

      Ja das hatte ich vor.

      Meiner Meinung nach solltest Du zwei Funktionen benutzen. Die erste ist eine Callback-Funktion, die von den beiden Ajax-Calls mit dem jeweiligen Ergebnis (auch wenn der Call an sich scheitert!) "gefüttert" wird, um dann zu prüfen, ob der gerade eingegangene Ajax-Call bereits der zweite eingetroffene war. In diesem Fall kann diese erste Funktion nämlich die zweite Funktion aufrufen, die das Formular abschickt, oder eben zurückweist.

      Was machst Du, wenn kein JavaScript verfügbar ist?

      Dann validiere ich nicht sondern schicke das Formular einfach so ab. Es soll nur ein zusätzlicher Service sein.

      Mein Problem ist, dass ja form_submit() den entsprechenden Wert zurückgeben muss, nicht die Callback-Funktion.

      Gruß,
      Felix

      1. Wobei ich natürlich form_submit() immer false zurückgeben lassen und dann per $(form).submit() das Formular in der Callback-Funktion gegebenenfalls abschicken könnte.

        Ja das ist anscheinend die Idee auf die ich seltsamerweise nicht gekommen bin.

        Danke :)

        Gruß,
        Felix

  3. Ich sitz gerade an folgendem Problem: ich möchte vor dem Absenden eines Formulars das Formular mittels Ajax überprüfen. Dafür muss ich zwei Ajax-Requests senden. [...]

    Diese Lösung kann ich in der Praxis natürlich nicht so verwenden. Hat jemand einen besseren Vorschlag? Zur Not müsste ich beide Checks in einen Request verpacken und den dann synchron abschicken, ist aber in meinem Fall ein wenig unelegant.

    Sehe ich auch so. Du musst den Ablauf Eventbasiert steuern. Also erst die requests absenden und das Formlar nicht abschicken. Und dann wenn beide Antworten gesendet wurden, entsprechend reagieren. Das ist mit JS auch kein Problem.

    In etwa so:
    <form (...) onsubmit="return form_submit(this)">

    function form_submit(f){  
      var count = 0;  
      Ajax.Request(  
        "/ajax1",  
        {  
          method: 'get',  
          parameters: '',  
          asynchronous: true,  
          onComplete: function(e){  
            if(is_valid && ++count == 2) f.submit();  
        }  
      );  
      Ajax.Request(  
        "/ajax2",  
        {  
          method: 'get',  
          parameters: '',  
          asynchronous: true,  
          onComplete: function(e){  
            if(is_valid && ++count == 2) f.submit();  
        }  
      );  
      return false;  
    }
    

    Struppi.