2013-07-31 16 views
7

Wenn ich innerhalb einer Schleife jQuery.ajax() aufrufen, würde es dazu führen, dass der Aufruf in aktueller Iteration den letzten Aufruf überschreibt oder ein neues XHR-Objekt für die neue Anforderung zugewiesen wird?jQuery.ajax() innerhalb einer Schleife

Ich habe eine Schleife, die dies tun, während aus dem Konsolenprotokoll kann ich Anfragen 200 ok erledigt sehen, aber nur die Ergebnisdaten der letzten Anfrage in der Schleife wird von der Anfrage success callback wie angenommen gespeichert.

der Code:

var Ajax = { 
    pages: {}, 

    current_request: null, 

    prefetch: function() { 
     currentPath = location.pathname.substr(1); 

     if(this.pages[currentPath]) 
     { 
      var current = this.pages[currentPath]; 
      delete this.pages[currentPath]; 

      current['name']=currentPath; 
      current['title']=$("title").text().replace(' - '.SITE_NAME, ''); 
      current['meta_description']=$("meta[name=description]").attr('content'); 
      current['meta_keywords']=$("meta[name=keywords]").attr('content');   
     } 

     var _Ajax = this; 
     //the loop in question ***** 
     for(var key in this.pages) 
     { 
      $.ajax({ 
       method: 'get', 
       url:'http://'+location.hostname+'/'+key, 
       success: function(data) { 
        _Ajax.pages[key] = data;  
       } 
      }); 

        console.debug(this.pages); 
     } 

     if(current) 
     { 
      this.pages[currentPath] = current; 
     }  

    } 
};//Ajax Obj 
for(var i in pages) 
{ 
    Ajax.pages[pages[i]]={}; 
} 

$(function() { 
    Ajax.prefetch(); 
});//doc ready 
+2

Mehrere AJAX-Aufrufe werden entsprechend behandelt. Wenn Sie jedoch Werte einer außerhalb des Bereichs des Rückrufs definierten Variablen zuweisen, wird diese möglicherweise überschrieben. Möchten Sie Code schreiben? –

+0

Ajax in einer regulären Schleife ist immer gefährlich, weil Ajax asynchron ist. Können wir etwas Code sehen? – musicnothing

Antwort

2

Dies ist, wie ich immer eine Ajax-Schleife tun ..

Ich benutze eine rekursive Funktion, die nach dem xhr.readyState == 4

i = 0 
process() 
function process() { 
    if (i < 10) { 
     url = "http://some.." + i 
     var xhr = new XMLHttpRequest(); 
     xhr.open("GET", url, true); 
     xhr.onreadystatechange = function() { 
      if (xhr.readyState == 4) { 
       alert(xhr.responseText) 
       i++ 
       process() 
      } 
     } 
     xhr.send(); 
    } else { 
     alert("done") 
    } 
} 
+0

Ihre Funktion führt die Anfragen nacheinander aus, was bedeutet, dass sie wahrscheinlich viel langsamer ausgeführt werden. Seine ursprüngliche Funktion war es, sie parallel zu betreiben. – idbehold

+2

true .. das ist absichtlich auf 1 auf einmal laufen .. vermeidet ein Flaschenhals Öffnung 100's der Anfrage auf einmal .. wirklich abhängt, was er zu tun versucht .. wenn er nur ein paar Anfragen öffnen dann tun sie alle auf einmal ist in Ordnung .. auch wenn es dir egal ist, welche Bestellung die Anfrage zurückkommt .. weil die 3. Anfrage könnte vor dem ersten .. – gezzuzz

6

aufgerufen wird, glaube ich, was ist passiert hier, hat mit der Schließung zu tun. In dieser Schleife:

for(var key in this.pages) 
    { 
     $.ajax({ 
      method: 'get', 
      url:'http://'+location.hostname+'/'+key, 
      success: function(data) { 
       _Ajax.pages[key] = data;  
      } 
     }); 

       console.debug(this.pages); 
    } 

Die Variable key tatsächlich außerhalb der Schleife definiert. Wenn Sie also zu den Callbacks kommen, hat sich der Wert wahrscheinlich geändert. Versuchen Sie so etwas wie dieses stattdessen:

http://jsfiddle.net/VHWvs/

var pages = ["a", "b", "c"]; 

for (var key in pages) { 
    console.log('before: ' + key); 
    (function (thisKey) { 
     setTimeout(function() { 
      console.log('after: ' + thisKey); 
     }, 1000); 
    })(key); 
} 
+0

Ihre Antwort sollte korrekt sein, aber in der Praxis ergab es das gleiche Ergebnis, wird thisKey auch überschrieben? – MTVS

+0

Ich denke nicht, dass dies wie erwartet funktionieren wird, da es keine Schließung ist. so wird 'thiskey' wahrscheinlich immer der letzte für jeden Ajax-Callback sein. – Andy

+0

Sieht so aus, als hätte ich das Problem, aber nicht die Lösung. Hier ist eine Lösung, die funktioniert, obwohl ich nicht weiß, ob es das beste ist: http://jsfiddle.net/VHWvs/ –

24

Sie werden für key einen Verschluss benötigen:

for(var k in this.pages){ 
    (function(key){ 
      $.ajax({ 
       method: 'get', 
       url:'http://'+location.hostname+'/'+key, 
       success: function(data) { 
        _Ajax.pages[key] = data;  
       } 
      }); 

      console.debug(this.pages); 
    })(k); 
} 

auf diese Weise sichergestellt werden, dass Schlüssel auf in jedem Ajax Erfolg immer die richtige ist Rückrufen. aber außer, dass es funktionieren sollte

i eine kleine Verschluss Demonstration mit Timeout statt Ajax aber das Prinzip gemacht ist das gleiche:

http://jsfiddle.net/KS6q5/

+0

Ja, danke, das funktioniert sehr gut, aber ich denke, es ist klarer, den Schlüssel zum '$ .ajax Optionsargument 'hinzuzufügen und darauf zuzugreifen, indem' this' Schlüsselwort im 'success' Callback – MTVS

3

ich vor der gleichen Situation war, löste ich die Verwendung von Ajax Aufruf innerhalb einer neuen Funktion dann rufen Sie die Funktion in die Schleife.

Es wäre wie folgt aussieht:

function a(){ 
    for(var key in this.pages) 
    { 
     var paramsOut [] = ... 
     myAjaxCall(key,paramsOut); 
     ....... 
    } 
} 
function myAjaxCall(paramsIn,paramsOut) 
{ 
     $.ajax({ 
     method: 'get', 
     url:'http://'+location.hostname+'/'+paramsIn[0], 
     success: function(data) { 
      paramsOut[key] = data;  
     } 
     }); 
} 
+0

+1 verwendet wird, weil ich dasselbe mache Wahl, aber Beispiel fehlt. – Mike

+0

Ich habe gerade das Beispiel – JPRLCol

7

Sie benötigen async verwenden: false in Sie Ajax-Request. Er sendet die Ajax-Anforderung synchron, während er auf die Beendigung der vorherigen Anforderung wartet und dann die nächste Anforderung sendet.

+0

Ich habe keine Ahnung, was es tut, aber es funktioniert. Danke für deine Arbeit – user3423149

Verwandte Themen