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);
- 如何在nodejs中获得ReferenceError的详细信息
- 带getter和setter的JavaScript类会导致RangeError:超出最大调用堆栈大小
- Node.js抓取,转换图像src – >完整的URL
- Node.js + Express – 无法连接。 ERR_CONNECTION_REFUSED
- 当写入数据库的并发API调用发生时(或者当服务器速度较慢时)阻止争用条件
- 使用Node的serialportcallback模拟/unit testing
- 使用Node.js和SSH2从SFTP服务器读取文件
- 哪个技术栈(模块,框架)更适合于第一个node.js项目,以便研究节点并做出好的产品?
- 用angularJS更新mongodb中的date,inputtypes=“date”