node 使用 async 控制并发的方法


Posted in Javascript onMay 07, 2018

目标

建立一个 lesson5 项目,在其中编写代码。

代码的入口是 app.js,当调用 node app.js 时,它会输出 CNode(https://cnodejs.org/ ) 社区首页的所有主题的标题,链接和第一条评论,以 json 的格式。

注意:与上节课不同,并发连接数需要控制在 5 个。

输出示例:

[
 {
  "title": "【公告】发招聘帖的同学留意一下这里",
  "href": "http://cnodejs.org/topic/541ed2d05e28155f24676a12",
  "comment1": "呵呵呵呵"
 },
 {
  "title": "发布一款 Sublime Text 下的 JavaScript 语法高亮插件",
  "href": "http://cnodejs.org/topic/54207e2efffeb6de3d61f68f",
  "comment1": "沙发!"
 }
]

知识点

学习 async(https://github.com/caolan/async ) 的使用。这里有个详细的 async demo 演示:https://github.com/alsotang/async_demo

学习使用 async 来控制并发连接数。

课程内容

lesson4 的代码其实是不完美的。为什么这么说,是因为在 lesson4 中,我们一次性发了 40 个并发请求出去,要知道,除去 CNode 的话,别的网站有可能会因为你发出的并发连接数太多而当你是在恶意请求,把你的 IP 封掉。

我们在写爬虫的时候,如果有 1000 个链接要去爬,那么不可能同时发出 1000 个并发链接出去对不对?我们需要控制一下并发的数量,比如并发 10 个就好,然后慢慢抓完这 1000 个链接。

用 async 来做这件事很简单。

这次我们要介绍的是 async 的 mapLimit(arr, limit, iterator, callback) 接口。另外,还有个常用的控制并发连接数的接口是 queue(worker, concurrency),大家可以去 https://github.com/caolan/async#queueworker-concurrency 看看说明。

这回我就不带大家爬网站了,我们来专注知识点:并发连接数控制。

对了,还有个问题是,什么时候用 eventproxy,什么时候使用 async 呢?它们不都是用来做异步流程控制的吗?

我的答案是:

当你需要去多个源(一般是小于 10 个)汇总数据的时候,用 eventproxy 方便;当你需要用到队列,需要控制并发数,或者你喜欢函数式编程思维时,使用 async。大部分场景是前者,所以我个人大部分时间是用 eventproxy 的。

正题开始。

首先,我们伪造一个 fetchUrl(url, callback) 函数,这个函数的作用就是,当你通过

fetchUrl('http://www.baidu.com', function (err, content) {
 // do something with `content`
});

调用它时,它会返回 http://www.baidu.com 的页面内容回来。

当然,我们这里的返回内容是假的,返回延时是随机的。并且在它被调用时,会告诉你它现在一共被多少个地方并发调用着。

// 并发连接数的计数器
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);
};

我们接着来伪造一组链接

var urls = [];
for(var i = 0; i < 30; i++) {
 urls.push('http://datasource_' + i);
}

这组链接的长这样:

node 使用 async 控制并发的方法

接着,我们使用 async.mapLimit 来并发抓取,并获取结果。

async.mapLimit(urls, 5, function (url, callback) {
 fetchUrl(url, callback);
}, function (err, result) {
 console.log('final:');
 console.log(result);
});

运行输出是这样的:

node 使用 async 控制并发的方法

可以看到,一开始,并发链接数是从 1 开始增长的,增长到 5 时,就不再增加。当其中有任务完成时,再继续抓取。并发连接数始终控制在 5 个。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
Sep 20 Javascript
基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
May 11 Javascript
基于javascript实现窗口抖动效果
Jan 03 Javascript
EasyUi combotree 实现动态加载树节点
Apr 01 Javascript
Bootstrap所支持的表单控件实例详解
May 16 Javascript
微信小程序 时间格式化(util.formatTime(new Date))详解
Nov 16 Javascript
Javascript 一些需要注意的细节(必看篇)
Jul 08 Javascript
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
Aug 19 Javascript
详解小程序中h5页面onShow实现及跨页面通信方案
May 30 Javascript
ES6 Map结构的应用实例分析
Jun 26 Javascript
js tab栏切换代码实例解析
Sep 03 Javascript
js模拟实现烟花特效
Mar 10 Javascript
Angular 数据请求的实现方法
May 07 #Javascript
JavaScript数组去重算法实例小结
May 07 #Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
May 07 #Javascript
详解VUE-地区选择器(V-Distpicker)组件使用心得
May 07 #Javascript
JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】
May 07 #Javascript
Vue 实现树形视图数据功能
May 07 #Javascript
JavaScript 跨域之POST实现方法
May 07 #Javascript
You might like
比较全面的PHP数组的使用方法小结
2010/09/23 PHP
在WAMP环境下搭建ZendDebugger php调试工具的方法
2011/07/18 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
2012/07/16 PHP
php中的字符编码转换函数用法示例
2014/10/20 PHP
PHP模板引擎Smarty自定义变量调解器用法
2016/04/11 PHP
Code:findPosX 和 findPosY
2006/12/20 Javascript
jquery ready()的几种实现方法小结
2010/06/18 Javascript
基于jquery的checkbox下拉框插件代码
2010/06/25 Javascript
JavaScript 打地鼠游戏代码说明
2010/10/12 Javascript
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
jQuery建立一个按字母顺序排列的友好页面索引(兼容IE6/7/8)
2013/02/26 Javascript
jQuery点击弹出下拉菜单的小例子
2013/08/01 Javascript
js 数组操作之pop,push,unshift,splice,shift
2014/01/29 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
javascript中的Function.prototye.bind
2015/06/25 Javascript
jquery点击缩略图切换视频播放特效代码分享
2015/09/15 Javascript
用nodejs的实现原理和搭建服务器(动态)
2016/08/10 NodeJs
微信小程序之购物车功能
2020/09/23 Javascript
vue.js获取数据库数据实例代码
2017/05/26 Javascript
手把手教你把nodejs部署到linux上跑出hello world
2017/06/19 NodeJs
webpack+vuex+axios 跨域请求数据的示例代码
2018/03/06 Javascript
vue修改对象的属性值后页面不重新渲染的实例
2018/08/09 Javascript
jQuery轮播图实例详解
2018/08/15 jQuery
webstorm+vue初始化项目的方法
2018/10/18 Javascript
python发送邮件的实例代码(支持html、图片、附件)
2013/03/04 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
Python动态导入模块和反射机制详解
2020/02/18 Python
Python Serial串口基本操作(收发数据)
2020/11/06 Python
New Era英国官网:美国棒球帽品牌
2018/03/21 全球购物
应届毕业生求职信范例分享
2013/12/17 职场文书
函授毕业自我鉴定
2013/12/19 职场文书
劳动模范事迹材料
2014/01/19 职场文书
女方家长婚礼答谢词
2015/09/29 职场文书
Python中相见恨晚的技巧
2021/04/13 Python
阿里云服务器部署mongodb的详细过程
2021/09/04 MongoDB
bose降噪耳机音能消除人声吗
2022/04/19 数码科技