2017-05-22 2 views
-1

Ich versuche, mehrere AJAX-Anfrage innerhalb einer for-Schleife zu senden. Ich muss sicherstellen, dass die Antworten mit der richtigen Anfrage verknüpft werden. Ich folge der Lösung, die hier gepostet wird XMLHttpRequest in for loop Hier ist FileBatches die Größe der Schleife. Ich versuche, die Antwort zu erfassen, die die Information über die Anzahl der erfolgreichen und fehlgeschlagenen Anforderungen enthält, und versucht, sie in _finalResponseArray zu speichern. Wenn die Länge der fileBatches 3 ist, besteht die Möglichkeit, dass die erste Anfrage länger dauert als andere Anfragen. Berücksichtigen Sie die erste Anforderung, dauert es einige Zeit zu verarbeiten und die zweite Anforderung und die dritte Anforderung wären abgeschlossen und die erste Anforderung wäre abgeschlossen. Ich muss sicherstellen, dass die richtige Anfrage mit der richtigen Antwort verknüpft wird. Hier, wenn die erste Schleife beginnt (i = 0), dauert es eine gewisse Zeit, bis sie verarbeitet wird und bis die zweite Schleife beginnt (i = 1) und verarbeitet wird. XHR [i] .readyState == 4 (da ich 1 inkrementiert habe und wie man den Wert von i = 0 bekommt?) Verwirrt und ich bin nicht in der Lage, die Antwort mit der richtigen Anfrage verknüpft zu bekommen. Bitte finden Sie den Code unten. Die folgende Funktion wird für mehrere AJAX-Anfragen ausgeführt.Wie XMLHTTP Request zu Recht verknüpfen Antwort im Falle mehrerer AJAX-Anfrage in einer Schleife

var XHR = []; 
var fileBatches = "Calling a function which returns array of values that needs to be processed" 
var _finalResponseArray = []; 
for (var i = 0; i < fileBatches.length; i++) 
{ 
    (function(i) 
    { 
     finalBatch = [] 
     finalBatch.push("Things that need to be processed by controller"); 

     finalData = finalBatch.join('&').replace(/%20/g, '+'); // Sending the values in a format so that it will be received by controller 

     XHR[i] = new XMLHttpRequest(); 

     console.log(i); 

     XHR[i].open('POST', theURL); 

     XHR[i].onreadystatechange = function (event) 
     { 
      console.log("Here"); 
      if (XHR[i].readyState == 4) 
      {    
      console.log("This request is complete"); 
      console.log("I value is " + i); 
      if (XHR[i].status == 200) 
      { 
      _finalResponseArray.push(XHR[i].responseText); 
      console.log("Inside" + _finalResponseArray); 
      }   
     } 
    } 

    XHR[i].setRequestHeader('accept', 'text/JSON'); 

    XHR[i].send(finalData); 
    })(i); 
} 

Ich bin nicht sicher, was ich hier falsch mache, aber die Anforderungen werden nicht verknüpft zu werden Antworten korrigieren und sie wird zufällig _finalResponseArray hinzugefügt. Es funktioniert perfekt, wenn es nur eine Anfrage ohne Schleife gibt. Wie stellen Sie sicher, dass onreadystatechange für die richtige Schleife überprüft wird?

********** Updates

Versuchte Lösung wie in den Kommentaren vorgeschlagen und auch verschiedene andere Ansätze (bezogen letzte Fragen in Stapelüberlauf):

Auch wenn ich versuche, Verschlüsse zu verwenden die Antwort vermasselt. Für alle 3 Anfragen wählt es zufällig eine Antwort aus und erzeugt dieselbe Antwort für alle 3 Anfragen.

Sollte meine Anfrage etwas Einzigartiges haben, so dass die Antwort es richtig verfolgen kann. Ich sehe, dass der Iterator-Wert 'i' an die URL angehängt wurde, als wir ant GET oder POST Anfrage senden wollten, aber ich sende nur dieselbe URL für verschiedene Anfragen. Spielt das eine Rolle?

+0

Ihre Vertiefung macht den Code unmöglich –

+0

lesen vermutlich 'finalBatch' irgendwo delcared ** nicht ** in dem Code, den Sie habe gepostet - und jede Schleife wird es sofort überlisten - Sie brauchen wahrscheinlich auch nicht das 'XHR' Array, denn warum brauchen Sie Zugriff auf alle XHRs außerhalb der Schleife? –

+0

Da 'XMLHttpRequest's asynchron sind, gibt es keine Garantie, in welcher Reihenfolge sie abgeschlossen werden, also keine Garantie, in welcher Reihenfolge die Ergebnisse auf das Ergebnis-Array übertragen werden - versuchen Sie' _finalResponseArray [i] = XHR.responseText; 'wenn Sie Erfordern Sie die richtige Reihenfolge - beachten Sie, dass _finalResponseArray kann leere Steckplätze haben, wenn einige Anforderungen fehlschlagen, und das wiederum aufgrund der asynchronen Natur von XHR, gibt es keine Möglichkeit zu wissen (mit Ihrem aktuellen Code), wenn alle Anforderungen abgeschlossen sind –

Antwort

1

Sie können die on_readystatechange-Funktionslogik in eine eigene Funktionsdefinition ziehen, um den Bereich lokal zu verwalten. Versuchen Sie folgendes:

var XHR = []; 
var _finalResponseArray = []; 

var createReadyStateChangeCb = function(responseIdx) 
{ 
    return function(event) 
    { 
     console.log("Here"); 
     if (XHR[responseIdx].readyState == 4) 
     {    
      console.log("This request is complete"); 
      console.log("I value is " + responseIdx); 
      if (XHR[responseIdx].status == 200) 
      { 
      _finalResponseArray.push(XHR[responseIdx].responseText); 
      console.log("Inside" + _finalResponseArray); 
      } 
     } 
    } 
} 

for (var i = 0; i < fileBatches.length; i++) 
{ 
    (function(i) 
    { 
     finalBatch = [] 
     finalBatch.push("Things that need to be processed by controller"); 

     finalData = finalBatch.join('&').replace(/%20/g, '+'); // Sending the values in a format so that it will be received by controller 

     XHR[i] = new XMLHttpRequest(); 

     console.log(i); 

     XHR[i].open('POST', theURL); 

     XHR[i].onreadystatechange = createReadyStateChangeCb(i); 
    } 

    XHR[i].setRequestHeader('accept', 'text/JSON'); 

    XHR[i].send(finalData); 
    })(i); 
} 
+0

Durch den Aufruf, XHR [i] .onreadystatechange = createReadyStateChangeCb (ich); - sagen meine erste Schleife dauert irgendwann (i = 0) und onreadystatechange wurde nicht erkannt, zu der Zeit, zweite Schleife (i = 1) gestartet und abgeschlossen und nun, wie on_readystatechange der ersten Schleife (XHR [0] .readystatechange) kann aufgerufen werden? –

+0

An die Person, die meine Frage abgelehnt hat, können Sie bitte Ihren Grund dafür angeben, damit Korrekturen für zukünftige Beiträge vorgenommen werden können? –

2

Erstens würde ich empfehlen die Verwendung von so XMLHttpRequest 2.0 genannt - statt der fiddly onreadystatechange Sachen, benutzen Sie einfach onload und onloadend (Sie werden sehen, warum diese im Code unten)

Durch die asynchrone Natur von XMLHttpRequest Sie können nicht vorhersagen, wenn die Anfragen alle fertig sind, werden so _finalResponseArray nur vollständig sein, sobald der endgültige onloadend abgeschlossen ist

Sie, was Sie tun können eine Anzahl von kompletten Anfragen Hinzufügen nee d im onloadend Rückruf, sobald alle Anfragen beendet sind.onloadend genannt wird, unabhängig von Erfolg oder Misserfolg

ich auch .forEach anstelle von IIFE

var fileBatches = "Calling a function which returns array of values that needs to be processed" 
var _done = 0; 
var _count = fileBatches.length; 
var _finalResponseArray = []; 

fileBatches.forEach(function(item, i) { 
    var finalBatch = [] 
    var xhr = new XMLHttpRequest(); 
    finalBatch.push("Things that need to be processed by controller"); 
    finalData = finalBatch.join('&').replace(/%20/g, '+'); // Sending the values in a format so that it will be received by controller 

    xhr.open('POST', theURL); 
    xhr.onload = function (event) { 
     if (xhr.status == 200) { 
      _finalResponseArray[i] = (xhr.responseText); 
     }   
    }; 
    xhr.onloadend = function (event) { 
     // this gets called in ALL cases, i.e. after load, error or abort 
     if(++_done == _count) { 
      // _finalResponseArray is complete here 
     } 
    }; 
    xhr.setRequestHeader('accept', 'text/JSON'); 
    xhr.send(finalData); 
}); 
//_finalResponseArray will ALWAYS be empty here 
+0

Vielen Dank für den Vorschlag. Ich verstehe das asynchrone Programm besser, weil ich gerade an diesem Projekt arbeite. Nur zur Klarstellung, glauben Sie, dass xhr.onload und xhr.onloadend außerhalb der ForEach-Schleife deklariert werden sollten? Da es Zeit braucht, um xhr.onload zu erkennen (wie es von der Verarbeitungszeit des Controllers abhängt), wird die Schleife fortgesetzt und abgeschlossen, bevor die Zeit Onload und Onloadend erkannt wird und aus der Schleife kommt, bevor Onload und Onloadend ausgeführt werden können. Auch warum sollten wir Item und ich an die Funktion übergeben? Ich weiß, dass ich innerlich benutzt werde. –

+0

XHR [i] .status == 200 sollte xhr.status == 200 sein, habe ich recht? –

+0

yep, habe den Code nicht vollständig überprüft: p –

Verwandte Themen