我正在尝试编写一个函数,它将3个url作为命令行参数,并以正确的顺序记录它们的内容。
我使用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 :(得分:1)
如果回复完成,你只是转移。因此,如果while循环运行,它永远不会移动,你有无限。可以简单地在循环中移位,例如:
while(urls.length){
var url=urls.shift();
...
}
答案 1 :(得分: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
模块,那么您必须在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);
}