2016-05-24 16 views
2

Ich habe einige Probleme beim Erstellen einer HTTP-Anfrage innerhalb einer Schleife.Http Anfrage innerhalb einer Schleife

Lassen Sie mich erklären, was ich habe ....

Ich mache eine HTTP-GET einige Werte abzurufen, und dann brauche ich eine andere HTTP GET für jedes Paar von Werten zu machen, die ich von der ersten nur genommen haben anfordern.

Die zwei Anrufe sind in Ordnung, und wenn ich den for Zyklus unterbringe und versuche, die ganze Anforderungskette zu laufen, funktioniert es tadellos, aber gerade einmal, seitdem ich den Zyklus entfernte. Wie kann ich es zum Laufen bringen?

Hier ist der Code:

request({ 
url: "some_url", 
    method: "GET", 
    json:true, 
    headers:[{'content-type': 'application/json'}] 
    }, function (error, response, body){ 
      if(!error & response.statusCode === 200){   
       for(var i=0;i<body.length;i++){ 
        for(var j=i;j<body.length-1;j++){ 
         //if(i === body.length-1) return; 
         src = body[i].name; 
         dest = body[j+1].name; 
         console.log("sorgente ",sorg); 

         request({ 
          url: "https://maps.googleapis.com/maps/api/distancematrix/json?origins="+src+"&destinations="+dest, 
          method: "POST", 
          json:true, 
          headers:[{'content-type': 'application/json'}] 
         }, function (error, response, body){ 
          if(!error & response.statusCode === 200){ 
           console.log("TIME ",body.rows[0].elements[0].duration.text); 
           return; 
          }else{ 
           console.log("google API failed!: "); 
           return; 
          } 
         }); 

        } 
       } 

      }else{ 
       console.log("/google_api failed!: "); 
       return; 
      } 
}); 

Ich hoffe, ich war mit der Frage klar.

+0

Siehe http: // stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-beispiel –

Antwort

5

Das Problem hier ist eines von Javascript Scoping und Tippfehler.

Zuerst haben Sie die Array-Indizes body[0] und body[1] fest codiert. Es sieht so aus, als ob Sie damit die Loop-Variablen gemeint haben.

Zweitens eine Übersicht über Ihre Scoping Problem in vereinfachter pseudo-Javascript:

var requestList = [...]; 

for(var i = 0; i < requestList.length; i++){ 
    var current = requestList[i]; 

    // make a request based on current or the data 
    // in current. 
    request(..., function(result){ 
     // do something with the current variable 
     current.foo = result.bar; 
    }); 
} 

Alle Web-Anfragen asynchron sind. Früher gab es eine Möglichkeit, sie zu zwingen, synchron zu laufen, aber es ist in den meisten gängigen Browsern veraltet. Dies bedeutet, dass die Anfrage gestellt wird, und möglicherweise eine Antwort erhalten, außerhalb Ihrer tatsächlichen Code, und ruft dann eine Art Rückruf - in diesem Fall die anonyme innere Funktion function(result){...}.

Was dies bedeutet, ist, dass die für die Schleife auszuführen und Schleife wird fortgesetzt, während der Antrag gestellt wird, das heißt, wenn die Anfrage nicht schnell genug ist, wird current aktualisieren und anders sein, wenn der Antrag zurückkommt, und so wird die for-Schleife Variablen.

Die Lösung, die ich für diese Art von Sache lief, ist Funktion scoping out die innere Anfrage in der for-Schleife.

Statt die neue Anforderung der Herstellung direkt in der for-Schleife, Sie, dass auf seine eigene Funktion ausrücken:

var requestList = [...]; 

for(var i = 0; i < requestList.length; i++){ 
    var current = requestList[i]; 

    GetMyResourceData(current); 
} 

function GetMyResourceData(current){ 
    request(..., function(result){ 
     // do something with the current variable 
     current.foo = result.bar; 
    }); 
} 

Jedes Mal, wenn die GetMyResourceData Funktion aufgerufen wird, ein neuer Rahmen für diese Funktion geschaffen wird, so Die Variable current in dieser Funktion wird gehalten, wenn Sie den Rückruf erreichen.

Also, das ist, was ich Ihnen empfehlen würde für Ihren Code. Verschieben Sie die zweite Anforderung außerhalb der for-Schleife in einen eigenen Bereich.

+0

Ich habe versucht, wie Sie vorgeschlagen, aber es scheint, wie es die for-Schleife nicht sieht, führt das Programm die Zeile kurz vor der für und dann hört es auf. Ich kann nicht herausfinden warum. – Mirko

+0

Bearbeiten: Gelöst! Aus irgendeinem unbekannten Grund schrieb ich schlecht die for-Schleife, der inkrementelle Teil war als zweites Argument anstelle der letzten. Ich fühle mich jetzt dumm, danke für die Hilfe! – Mirko

+0

Ich habe nur Ihre Kommentare gesehen, froh zu wissen, dass ich Ihnen helfen konnte! Lassen Sie mich wissen, wenn Sie weitere Fragen haben. – Aeolingamenfel

0

Haben Sie vergessen, Ihre Schleifenvariablen i und j zu verwenden. Der obige Code wird weiterhin Anfragen mit body [0] als src und body [1] als dest für die Dauer der Schleife stellen Körper Körper hat Länge> = 2. Versuchen Sie https://github.com/caolan/async#forEachOf oder https://github.com/caolan/async#each für den Aufruf von asynchronen Funktionen in einer Schleife.

+0

Ja, es war ein Fehler beim Kopieren und Einfügen, offensichtlich sind die Variablen Körper [i] und Körper [j + 1], ich bearbeite in der Frage, danke :) – Mirko

+0

Ich finde caolan Async-Modul sehr nützlich beim Aufruf von vielen asynchronen Funktionen parallel –

Verwandte Themen