1.用 eventproxy 实现控制并发:

var EventProxy = require('eventproxy');

const most = 5;//并发数5
var urllist = [....];//待抓取url列表,100个 function foo(start){
var ep = new EventProxy();
ep.after('ok',most,function(){
foo(start+most);//一个批次任务完成,递归进行下一批任务
});
var q=0;
for(var i=start;i<urllist.length;i++){
if(q>=most){
break;//最多添加most个任务
}
http.get(urllist[i],function(res){
//....
res.on('end',function(){
ep.emit('ok');//一个任务完成,触发一次ok事件
});
});
q++;
}
}
foo(0);

2.使用 async.mapLimit 控制并发

var async = require('async');

//模拟一组连接地址
var urls = [];
for(var i = 0; i < 30; i++) {
urls.push('http://datasource_' + i);
}
console.log(urls); // 并发连接数的计数器
var concurrencyCount = 0; // 并发抓取数据的过程
var fetchUrl = function (url, callback) {
// delay 的值在 2000 以内,是个随机的整数
var delay = parseInt((Math.random() * 10000000) % 2000, 10);
concurrencyCount++;
console.log('现在的并发数是', concurrencyCount, ',正在抓取的是', url, ',耗时' + delay + '毫秒');
setTimeout(function () {
concurrencyCount--;
//抓取成功,调用回调函数
callback(null, url + ' html content');
}, delay);
}; //使用 async.mapLimit 来 5 个并发抓取,并获取结果
async.mapLimit(urls, 5, function (url, callback) {
fetchUrl(url, callback);
}, function (err, result) {
//所有连接抓取成功,返回回调结果列表
console.log('final:');
console.log(result);
});

3.async.queue 非常合适用来控制并发

/**
* Created by admin on 16/3/20.
*/
"use strict"
var http = require('http');
var cheerio = require('cheerio');
var URL = require('url');
var path = require('path');
var fs = require('fs');
var async = require('async'); var baseUrl = "http://cnodejs.org/";
var targetUrl = "http://cnodejs.org/";
var stime = new Date(); function sGet(url,callback){
var chunks = [];
http.get(url,(res)=>{
if (res.statusCode != '200') {
callback({message:"抓取失败,状态码:"+res.statusCode,url:url});
return;
}
res.on('data',(chunk)=>{
chunks.push(chunk);
});
res.on('end',()=>{
callback(null,Buffer.concat(chunks).toString());
});
}).on('error',(e)=>{
callback({message:"抓取失败",url:url,err:e});
});
} sGet(targetUrl,(err,data)=>{
if (err) {
console.log(err);
return false;
}
var $ = cheerio.load(data);
var anchors = $("#topic_list a.topic_title");
console.log('共'+anchors.length+'个任务'); const most=5;//并发数
//创建队列并指定并发数
var q=async.queue(function(url,callback){
var filename = path.basename(url)+'.txt';
sGet(url, (err, data)=> {
if (err) {
callback(err);
return false;
}
fs.writeFile('./html/' + filename, data, function (err) {
if (err) {
throw err;
}
callback(null,filename);
});
});
},most); q.drain = function() {
console.log('任务全部完成,共耗时:'+(new Date()-stime)+'ms');
} anchors.each(function(){
var url = URL.resolve(baseUrl,$(this).attr('href'));
q.push(url,function(err,filename){
if (err) {
console.log(err);
return;
}
console.log("finished:"+filename);
});
});
});

最新文章

  1. 移动App崩溃的测试用例设计
  2. RabbitMQ 一二事 - 简单队列使用
  3. Adobe Scout 入门
  4. NeHe OpenGL教程 第三十八课:资源文件
  5. javaSE第二十七天
  6. 在Linux下怎么确定哪个网卡对应哪个接口?
  7. [JavaScript] 怎么使用JS禁止复制粘贴
  8. thinkphp关联查询(多表查询)
  9. angularjs学习总结(~~很详细的教程)
  10. 引用:初探Sql Server 执行计划及Sql查询优化
  11. bitmap 加载的时候出现OOM,nullpointer
  12. SQL Server-聚焦事务对本地变量、临时表、表变量影响以及日志文件存满时如何收缩(三十一)
  13. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(三)用户接口层之RTSP命令
  14. 部署 k8s Cluster(上)- 每天5分钟玩转 Docker 容器技术(118)
  15. 微信H5支付网络环境未能通过安全验证,请稍后再试(获取终端ip )
  16. 怎樣添加設置GridView,CheckBox全選功能
  17. 20秒教你如何写maven2的pom文件的依赖包
  18. RBF:RBF基于近红外光谱的汽油辛烷值含量预测结果对比—Jason niu
  19. centos下安装djangobb
  20. 创建pod步骤

热门文章

  1. 在word上写博客直接发到CSDN博客
  2. HttpUploader6-queue版本更新说明
  3. Makefile模板
  4. Alpha冲刺(五)
  5. javascript高级程序设计读书笔记----事件
  6. C#基础入门 三
  7. Intel Galileo development documentation
  8. AgentJob--修改操作系统时间对Job的影响
  9. ZKEACMS 自定义表单的使用
  10. nowcoder(牛客网)OI测试赛3 解题报告