nodejs循环中的多个http请求

我试图在节点中制作简单的feed阅读器,并且在node.js中面临多个请求的问题。 例如,我得到了一些类似于Url的表格:

urls = [ "http://url1.com/rss.xml", "http://url2.com", "http://url3.com"]; 

现在我想要获取每个url的内容。 第一个想法是使用for(var i in urls)但这不是个好主意。 最好的select是asynchronous做,但我不知道如何做到这一点。

有任何想法吗?

编辑:

我得到了这个代码:

 var data = []; for(var i = 0; i<urls.length; i++){ http.get(urls[i], function(response){ console.log('Reponse: ', response.statusCode, ' from url: ', urls[i]); var body = ''; response.on('data', function(chunk){ body += chunk; }); response.on('end', function() { data.push(body); }); }).on('error', function(e){ console.log('Error: ', e.message); }); } 

问题是,首先是循环中的每个元素的呼叫线“http.get …”,并在该事件之后调用response.on('data'),然后在response.on('end')之后。 这使得混乱,我不知道如何处理这一点。

默认情况下,节点http请求是asynchronous的。 您可以在您的代码中按顺序启动它们,并调用一个将在所有请求完成时启动的函数。 你可以手工完成(计数已完成vs开始请求)或使用async.js

这是不依赖的方式(省略错误检查):

 var http = require('http'); var urls = ["http://www.google.com", "http://www.example.com"]; var responses = []; var completed_requests = 0; for (i in urls) { http.get(urls[i], function(res) { responses.push(res); completed_requests++; if (completed_requests == urls.length) { // All download done, process responses array console.log(responses); } }); } 

你需要检查end (数据完整事件)被称为确切的请求数量…这是一个工作的例子:

 var http = require('http'); var urls = ['http://adrianmejia.com/atom.xml', 'http://twitrss.me/twitter_user_to_rss/?user=amejiarosario']; var completed_requests = 0; urls.forEach(function(url) { var responses = []; http.get(url, function(res) { res.on('data', function(chunk){ responses.push(chunk); }); res.on('end', function(){ if (completed_requests++ == urls.length - 1) { // All downloads are completed console.log('body:', responses.join()); } }); }); }) 

我知道这是一个老问题,但我认为更好的解决scheme是使用JavaScript Promise.all()

 const request = require('request-promise'); const urls = ["http://www.google.com", "http://www.example.com"]; const promises = urls.map(url => request(url)); Promise.all(promises).then((data) => { // data = [promise1,promise2] } 

您可以使用任何具有“.all”实现的承诺库。 我使用RSVP库,它很简单。

 var downloadFileList = [url:'http://stuff',dataname:'filename to download'] var ddownload = downloadFileList.map(function(id){ var dataname = id.dataname; var url = id.url; return new RSVP.Promise(function(fulfill, reject) { var stream = fs.createWriteStream(dataname); stream.on('close', function() { console.log(dataname+' downloaded'); fulfill(); }); request(url).on('error', function(err) { console.log(err); reject(); }).pipe(stream); }); }); return new RSVP.hashSettled(ddownload);