2017-07-25 31 views
0

我想寫一個函數,將3個網址作爲命令行參數,並以正確的順序記錄他們的內容。爲什麼不是這個while循環調用它的內部函數?

我使用了一個while循環,所以我可以阻止http.get的執行,然後它的內容已經記錄在END的響應中。

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() 
    }) 
    }) 
} 

我必須做一些非常錯誤的,因爲代碼會導致一個無限循環(顯然urls.shift()不叫)。任何人都可以解釋錯誤?

+0

移動urls.shift()的異步代碼之外。 –

+0

AJAX調用是異步的。您將不得不使用回調鏈或承諾 – Rajesh

+0

您的當前代碼會執行異步調用,但您的'while'會阻止瀏覽器,直到所有請求都結束。它應該是無限循環 – Justinas

回答

1

這裏的問題轉移是while循環是非阻塞的,因爲http.get是非阻塞。所以你必須找出一種方法來使用回調按順序請求這些URL。如果你願意用async模塊,可以實現如下它...

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); 
}); 

如果你不想使用async模塊,那麼你就必須手動保持在待定的URL請求的軌道while循環如下所示。

請注意使用立即調用的函數表達式(IIFE)來跟蹤執行上下文中的當前URL。這需要做的事情,因爲你想要的結果相同,提供的URL中的順序相同的順序...

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

如果回答完成,您只需轉移。因此,如果while循環運行,它永遠不會改變,並且你有無窮大。可以簡單地在循環本身例如爲:

while(urls.length){ 
    var url=urls.shift(); 
    ... 
} 
相關問題