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 相关文章推荐
Javascript 布尔型分析
Dec 22 Javascript
js自执行函数的几种不同写法的比较
Aug 16 Javascript
Raphael带文本标签可拖动的图形实现代码
Feb 20 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
Sep 24 Javascript
js中精确计算加法和减法示例
Mar 28 Javascript
总结JavaScript中布尔操作符||与&amp;&amp;的使用技巧
Nov 17 Javascript
Javascript页面跳转常见实现方式汇总
Nov 28 Javascript
angular 基于ng-messages的表单验证实例
May 04 Javascript
JS与SQL方式随机生成高强度密码示例
Dec 29 Javascript
自定义javascript验证框架示例【附源码下载】
May 31 Javascript
node中实现删除目录的几种方法
Jun 24 Javascript
axios实现文件上传并获取进度
Mar 25 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中使用session_set_save_handler()函数把session保存到MySQL数据库实例
2014/11/06 PHP
php使用GD2绘制几何图形示例
2017/02/15 PHP
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
JavaScript替换当前页面的方法
2015/04/03 Javascript
js实现兼容IE、Firefox的图片缩放代码
2015/12/08 Javascript
基于jQuery实现动态搜索显示功能
2016/05/05 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
2016/05/27 Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
2016/09/02 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
jQuery插件HighCharts绘制2D带有Legend的饼图效果示例【附demo源码下载】
2017/03/10 Javascript
js获取指定时间的前几秒
2017/04/05 Javascript
vue搜索和vue模糊搜索代码实例
2019/05/07 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
[14:03]2017DOTA2亚洲邀请赛开幕式:12神兵演绎水墨中华
2017/04/01 DOTA
Python爬虫抓取手机APP的传输数据
2016/01/22 Python
Django的信号机制详解
2017/05/05 Python
在numpy矩阵中令小于0的元素改为0的实例
2019/01/26 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
检测python爬虫时是否代理ip伪装成功的方法
2019/07/12 Python
Django之创建引擎索引报错及解决详解
2019/07/17 Python
Pycharm最常用的快捷键及使用技巧
2020/03/05 Python
Python析构函数__del__定义原理解析
2020/11/20 Python
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
乌克兰巴士票购买网站:inBus
2021/03/12 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
造型师求职自荐信
2013/09/27 职场文书
土木工程专业自荐信
2013/10/04 职场文书
大学生冰淇淋店商业计划书
2014/01/14 职场文书
文明家庭先进事迹材
2014/01/27 职场文书
《跨越海峡的生命桥》教学反思
2014/02/24 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
党的群众路线教育实践活动制度建设计划方案
2014/10/31 职场文书
论群众路线学习心得体会
2014/10/31 职场文书
2016年高校自主招生自荐信范文
2015/03/24 职场文书
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js