2017-07-25 1 views
0

Ich versuche, eine Funktion zu schreiben, die 3 URLs als Befehlszeilenargumente nehmen und ihren Inhalt in der richtigen Reihenfolge protokollieren wird.Warum ruft diese While-Schleife nicht ihre inneren Funktionen auf?

Ich benutze eine while-Schleife, so dass ich die Ausführung von http.get blockieren kann, bevor ihr Inhalt am Ende selbst der Antwort protokolliert wurde.

var http = require('http') 

var url1 = process.argv[2] 
var url2 = process.argv[3] 
var url3 = process.argv[4] 

var urls = [url1, url2, url3] 


while (urls.length>0){ 
    var url = urls[0] 
    http.get(url, function callback(response){ 
    var chars = "" 
    response.on('data', function(data){ 
     chars+=data.toString() 
    }) 
    response.on('end', function(err){ 
     console.log(chars) 
     urls.shift() 
    }) 
    }) 
} 

ich etwas sehr falsch tun muss, weil Code in eine Endlosschleife verursacht (scheinbar urls.shift() aufgerufen wird nicht). Kann jemand den Fehler erklären?

+0

Verschieben Sie urls.shift() außerhalb des Async-Codes. –

+0

AJAX-Aufrufe sind asynchron. Sie müssen Callback-Kette oder Versprechen – Rajesh

+0

Ihr aktueller Code verwendet Async-Aufrufe, aber Ihre 'while' blockiert Browser, bis alle Anforderungen beendet sind. Es sollte Endlosschleife sein – Justinas

Antwort

1

Das Problem hierbei ist, dass die while-Schleife nicht blockierend ist, weil http.get nicht blockierend ist. Sie müssen also herausfinden, wie Sie diese URLs mithilfe von Rückrufen nacheinander anfordern können. Wenn Sie bereit sind async Modul zu verwenden, können Sie es wie folgt implementieren ...

var http = require('http'); 
var async = require('async'); 

var url1 = process.argv[2] 
var url2 = process.argv[3] 
var url3 = process.argv[4] 

var urls = [url1, url2, url3] 

var results = []; 

async.eachOf(urls, function(url, index, callback) { 
    http.get(url, function (res) { 
     var chars = ""; 
     res.on('data', function(data){ 
      chars += data.toString(); 
     }) 
     res.on('end', function(err){ 
      results[index] = (chars); 
      callback(null, chars); 
     }) 
    }) 
}, function (err) { 
    console.log(results); 
}); 

Wenn Sie nicht async Modul verwenden möchten, dann werden Sie manuell Spur anhängiger URL-Anforderungen halten müssen in die While-Schleife wie unten gezeigt.

Beachten Sie die Verwendung eines sofort aufgerufenen Funktionsausdrucks (IIFE), um die aktuelle URL im Ausführungskontext zu verfolgen. Dies muss durchgeführt werden, da die Reihenfolge der bereitgestellten URLs gleich sein soll.

var http = require('http'); 
var url1 = process.argv[2] 
var url2 = process.argv[3] 
var url3 = process.argv[4] 

var urls = [url1, url2, url3] 

var total = urls.length; 
var results = []; 
var processed = 0; 

while (urls.length>0){ 
    (function(url, index) { 
     http.get(url, function callback(response){ 
      var chars = "" 
      response.on('data', function(data){ 
       chars+=data.toString() 
      }) 
      response.on('end', function(err){ 
       results[index] = chars; 
       processed++; 

       if(processed === total) { 
        // do something with the result 
        console.log(results); 
       } 
      }) 
     }) 
    })(urls.shift(), total - urls.length - 1); 
} 
1

Sie verschieben nur, wenn eine Antwort abgeschlossen ist. Wenn also die while-Schleife läuft, wird sie niemals verschoben und du hast Infinity. einfach in der Schleife verschieben sich z.B .:

while(urls.length){ 
    var url=urls.shift(); 
    ... 
} 
Verwandte Themen