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实现点击链接弹出&quot;图片另存为&quot;而不是直接打开
Aug 15 Javascript
JS 排序输出实现table行号自增前端动态生成的tr
Aug 13 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
Jan 09 Javascript
js验证真实姓名与身份证号是否匹配
Oct 13 Javascript
JavaScript判断浏览器及其版本信息
Jan 20 Javascript
简单实现AngularJS轮播图效果
Apr 10 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
Sep 17 Javascript
vue拖拽组件使用方法详解
Dec 01 Javascript
JQuery表单元素取值赋值方法总结
May 12 jQuery
Postman无法正常返回结果问题解决
Aug 28 Javascript
webpack4从0搭建组件库的实现
Nov 29 Javascript
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
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
Apache实现Web Server负载均衡详解(不考虑Session版)
2013/07/05 PHP
WordPress开发中的get_post_custom()函数使用解析
2016/01/04 PHP
PHP面向对象程序设计类的定义与用法简单示例
2016/12/27 PHP
javascript Split方法,indexOf方法、lastIndexOf 方法和substring 方法
2009/03/21 Javascript
javascript解析json实例详解
2014/11/05 Javascript
javascript正则表达式之search()用法实例
2015/01/19 Javascript
动态加载jQuery的方法
2015/06/16 Javascript
基于jquery实现页面滚动时顶部导航显示隐藏
2020/04/20 Javascript
分享我对JS插件开发的一些感想和心得
2016/02/04 Javascript
js 实现一些跨浏览器的事件方法详解及实例
2016/10/27 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
2016/11/01 Javascript
详解微信小程序 页面跳转 传递参数
2016/12/08 Javascript
jquery实现瀑布流效果 jquery下拉加载新数据
2016/12/12 Javascript
jquery表单验证插件validation使用方法详解
2017/01/20 Javascript
JavaScript中Object值合并方法详解
2017/12/22 Javascript
中高级前端必须了解的JS中的内存管理(推荐)
2019/07/04 Javascript
Layui之table中的radio在切换分页时无法记住选中状态的解决方法
2019/09/02 Javascript
Vuex实现数据增加和删除功能
2019/11/11 Javascript
Vue的Options用法说明
2020/08/14 Javascript
微信小程序实现音乐播放页面布局
2020/12/11 Javascript
[48:45]Ti4 循环赛第二日 NEWBEE vs EG
2014/07/11 DOTA
[04:14]从西雅图到上海——玩家自制DOTA2主题歌曲应援TI9
2019/07/11 DOTA
使用Python的urllib2模块处理url和图片的技巧两则
2016/02/18 Python
python3.6+opencv3.4实现鼠标交互查看图片像素
2018/02/26 Python
Python Unittest自动化单元测试框架详解
2018/04/04 Python
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
2019/07/04 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
2019/11/19 Python
南非最大的在线时尚商店:Zando
2019/07/21 全球购物
经济管理专业毕业生自荐信范文
2014/01/02 职场文书
驻村工作先进事迹
2014/08/14 职场文书
标准离婚协议书(2014版)
2014/10/05 职场文书
2019年特色火锅店的创业计划书模板
2019/08/28 职场文书
创业计划书之淘宝网店
2019/10/08 职场文书
Python爬虫基础之简单说一下scrapy的框架结构
2021/06/26 Python
MySQL的安装与配置详细教程
2021/06/26 MySQL
阿里云服务器Ubuntu 20.04上安装Odoo 15
2022/05/20 Servers