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 相关文章推荐
文字幻灯片
Jun 26 Javascript
浏览器兼容console对象的简要解决方案分享
Oct 24 Javascript
js中的hasOwnProperty和isPrototypeOf方法使用实例
Jun 06 Javascript
C++中的string类的用法小结
Aug 07 Javascript
使用canvas及js简单生成验证码方法
Apr 02 Javascript
详解webpack自动生成html页面
Jun 29 Javascript
jQuery使用zTree插件实现可拖拽的树示例
Sep 23 jQuery
使用 Javascript 实现浏览器推送提醒功能的示例
Nov 03 Javascript
angularjs实现的购物金额计算工具示例
May 08 Javascript
移动端手指操控左右滑动的菜单
Sep 08 Javascript
vue 实现路由跳转时更改页面title
Nov 05 Javascript
小程序自定义导航栏兼容适配所有机型(附完整案例)
Apr 26 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/10/12 PHP
php安装swoole扩展的方法
2015/03/19 PHP
java模拟PHP的pack和unpack类
2016/04/13 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
javascript hashtable 修正版 下载
2010/12/30 Javascript
获取当前点击按钮的id用this.id实现
2014/03/17 Javascript
javascript跨域方法、原理以及出现问题解决方法(详解)
2015/08/06 Javascript
javascript中对变量类型的判断方法
2015/08/09 Javascript
基于jquery实现人物头像跟随鼠标转动
2015/08/23 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
JQueryEasyUI框架下的combobox的取值和绑定的方法
2017/01/22 Javascript
让微信小程序支持ES6中Promise特性的方法详解
2017/06/13 Javascript
详解js静态资源文件请求的处理
2017/08/01 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
详解Angular5 服务端渲染实战
2018/01/04 Javascript
JS实现访问DOM对象指定节点的方法示例
2018/04/04 Javascript
详解如何使用webpack打包JS
2018/06/21 Javascript
移动端(微信等使用vConsole调试console的方法
2019/03/05 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
vue设置默认首页的操作
2020/08/12 Javascript
Js跳出两级循环方法代码实例
2020/09/22 Javascript
ES11新增的这9个新特性,你都掌握了吗
2020/10/15 Javascript
python中查找excel某一列的重复数据 剔除之后打印
2013/02/10 Python
Python中的groupby分组功能的实例代码
2018/07/11 Python
Django1.11配合uni-app发起微信支付的实现
2019/10/12 Python
Flask之pipenv虚拟环境的实现
2019/11/26 Python
python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法(实例代码)
2020/01/08 Python
python实现FTP文件传输的方法(服务器端和客户端)
2020/03/20 Python
python之语音识别speech模块
2020/09/09 Python
如何基于python实现年会抽奖工具
2020/10/20 Python
单身旅行者的单身假期:Just You
2018/04/08 全球购物
2014年消防工作实施方案
2014/02/20 职场文书
家长通知书教师评语
2014/04/17 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
土木工程生产实习心得体会
2016/01/22 职场文书