molily: $.get in schleife -.-

Beitrag lesen

var values = new Array("Wert1", "Wert2");
     $('#weekSelect').change(function(){
          week=$(this).val();
          for(i=0;i<values.length;i++){
          var keyVal=trackedValues[i];
          alert(keyVal); //1. Alert
          $.get(    "test.php",
                    {task:"fetchWeekData", week:week, key:keyVal},
                    function(data){
                         idKey="#"+keyVal;
                         alert(idKey); //2. Alert
                         $(idKey).html(data);
                         });
          }
     });

  
Das sieht wie das typische Problem »Funktion (Closure) in Schleife erzeugen« aus, das wurde hier im Forum schon dutzende Male diskutiert.  
  
Der Callback-Funktion wird ausgeführt, wenn die Schleife durchgelaufen ist. Die Lösung sollte möglichst NICHT sein, auf asynchrone Ajax-Requests umzusteigen. Wieso auch? Das macht die ganze Sache nur langsamer!  
  
Die Lösung ist, der Funktion einfach die richtigen Werte zu übergeben. Dazu könnte man eine weitere anonyme Funktion notieren (das ist die Standardlösung):  
  
~~~javascript
for (...) {  
  var keyVal = trackedValues[i];  
  (function (keyVal) {  
    $.get("test.php",  
          {task:"fetchWeekData", week:week, key:keyVal},  
          function(data) {  
            alert(keyVal);  
            $("#" + keyVal).html(data);  
          });  
  })(keyVal);  
}

Allerdings geht es hier etwas einfacher, ich würde den context-Parameter von jQuerys $.ajax() verwenden:

for (...) {  
  var keyVal = trackedValues[i];  
  $.ajax({  
    url: "test.php",  
    data: {task: "fetchWeekData", week: week, key: keyVal}  
    context: keyVal,  
    success: function(data){  
      alert(this);  
      $("#" + this).html(data);  
    }  
  );  
}

Im Handler kann man dann über »this« auf das übergebene context-Objekt zugreifen. In dem Fall ist es wahrscheinlich nur ein String oder eine Number, aber das ist egal.

Noch einfacher wäre e, im success-Handler auf data zugreifen zu können, denn darin steht der keyVal bereits. Aber ich wüsste nicht, wie das (ohne Closures) geht.

Problem ist, dass, wenn ich die alerts laufen lasse, ich erst zweimal das erste Alert gezeigt bekomme und dann zweimal das zweite Alert, er das $.get also nicht direkt ausführt wenn es in der schleife dran wäre, sondern erst hinterher und damit ist 'keyVal' immer "Wert2", statt erst "Wert1" und dann "Wert2".

Er muss den Code auch gar nicht hintereinander ausführen. Lass dich doch von den Alerts nicht verwirren. Alerts halten die JavaScript-Ausführung an. JavaScript und jQuery arbeiten aber fundamental asynchron. Das ist in Ordnung und an sich kein Problem.

Zweck ist doch, irgendwelche Elemente mit HTML zu füllen, das vom Server kommt. Richtig? Die Reihenfolge ist doch egal. Wobei die Requests durchaus in der gewünschten Reihenfolge rausgehen und vermutlich auch die Antworten eintrudeln. Also kann das ruhig asynchron laufen. Die Asynchronität ist hier nicht das Problem, sondern die Datenverfügbarkeit durch Closures in JavaScript. Und das kannst du relativ einfach lösen.

Mathias