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 相关文章推荐
使用jQuery插件创建常规模态窗口登陆效果
Aug 23 Javascript
JavaScript图片放大技术(放大镜)实现代码分享
Nov 14 Javascript
100个不能错过的实用JS自定义函数
Mar 05 Javascript
JS实现随机乱撞彩色圆球特效的方法
May 05 Javascript
jQuery之简单的表单验证实例
Jul 07 Javascript
AngularJs  Using $location详解及示例代码
Sep 02 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
Feb 17 Javascript
原生JS改变透明度实现轮播效果
Mar 24 Javascript
javascript计算对象长度的方法
Oct 25 Javascript
微信小程序城市选择及搜索功能的方法
Mar 22 Javascript
vue页面加载时的进度条功能(实例代码)
Jan 13 Javascript
vue项目中播放rtmp视频文件流的方法
Sep 17 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的array数组和使用实例简明教程(容易理解)
2014/03/20 PHP
PHP统计目录中文件以及目录中目录大小的方法
2016/01/09 PHP
Thinkphp 中 distinct 的用法解析
2016/12/14 PHP
微信公众号模板消息群发php代码示例
2016/12/29 PHP
让ThinkPHP的模板引擎达到最佳效率的方法详解
2017/03/14 PHP
PHP结合Ffmpeg快速搭建流媒体服务的实践记录
2018/10/31 PHP
漂亮的thinkphp 跳转页封装示例
2019/10/16 PHP
javascript编程起步(第六课)
2007/02/27 Javascript
js实现单行文本向上滚动效果实例代码
2013/11/28 Javascript
浅析javascript的间隔调用和延时调用
2014/11/12 Javascript
a标签的href与onclick事件的区别详解
2014/11/12 Javascript
JS实现点击颜色块切换指定区域背景颜色的方法
2015/02/25 Javascript
javascript常用的方法整理
2015/08/20 Javascript
js实现StringBuffer的简单实例
2016/09/02 Javascript
JS弹性运动实现方法分析
2016/12/15 Javascript
JSON与js对象序列化实例详解
2017/03/16 Javascript
JS数组操作中的经典算法实例讲解
2017/07/26 Javascript
jQuery中extend函数简单用法示例
2017/10/11 jQuery
JavaScript 跨域之POST实现方法
2018/05/07 Javascript
简化版的vue-router实现思路详解
2018/10/19 Javascript
微信小程序图片加载失败时替换为默认图片的方法
2019/12/09 Javascript
Python算法应用实战之队列详解
2017/02/04 Python
python中plot实现即时数据动态显示方法
2018/06/22 Python
Python3.5模块的定义、导入、优化操作图文详解
2019/04/27 Python
python networkx 根据图的权重画图实现
2019/07/10 Python
PyQt5实现画布小程序
2020/05/30 Python
html5-Canvas可以在web中绘制各种图形
2012/12/26 HTML / CSS
Daniel Wellington官方海外旗舰店:丹尼尔惠灵顿DW手表
2018/02/22 全球购物
关于运动会的稿件
2014/02/02 职场文书
求职信的七个关键技巧
2014/02/05 职场文书
党员公开承诺事项
2014/03/25 职场文书
勤奋学习演讲稿
2014/05/10 职场文书
乔迁之喜答谢词
2015/01/05 职场文书
在JavaScript中如何使用宏详解
2021/05/06 Javascript
C3 线性化算法与 MRO之Python中的多继承
2021/10/05 Python
JS轻量级函数式编程实现XDM二
2022/06/16 Javascript