async和enterproxy调控并发数量

参考资料

Node.js 包教不包会 –
alsotang

enterproxy

async

async Documentation

行使enterproxy调节并发数量

enterproxy是朴灵大大为重中之重进献的工具,带来1种事件式编制程序的盘算调换,利用事件机制解耦复杂工作逻辑,解决了回调函数耦合性的责难,将串行等待形成并行等待,提高多异步合作场景下的进行效用

小编们怎么接纳enterproxy调节并发数量?常常假使我们不利用enterproxy和自制的计数器,大家只要抓取多个源:

那种深层嵌套,串行的法子

var render = function (template, data) {
  _.template(template, data);
};
$.get("template", function (template) {
  // something
  $.get("data", function (data) {
    // something
    $.get("l10n", function (l10n) {
      // something
      render(template, data, l10n);
    });
  });
});

而外那种过去深层嵌套的主意,我们例行的写法的温馨维护叁个计数器

(function(){
    var count = 0;
    var result  = {};

    $.get('template',function(data){
        result.data1 = data;
        count++;
        handle();
    })
    $.get('data',function(data){
        result.data2 = data;
        count++;
        handle();
    })
    $.get('l10n',function(data){
        result.data3 = data;
        count++;
        handle();
    })

    function handle(){
        if(count === 3){
            var html = fuck(result.data1,result.data2,result.data3);
            render(html);
        }
    }
})();

在此地,enterproxy就能够起到那一个计数器的效果,它帮你管理那几个异步操作是否实现,实现之后,他会自行调用你提供的处理函数,并将抓取到数据作为参数字传送递过来

var ep = new enterproxy();
ep.all('data_event1','data_event2','data_event3',function(data1,data2,data3){
    var html = fuck(data1,data2,data3);
    render(html);
})

$.get('http:example1',function(data){
    ep.emit('data_event1',data);
})

$.get('http:example2',function(data){
    ep.emit('data_event2',data);
})

$.get('http:example3',function(data){
    ep.emit('data_event3',data);
})

enterproxy还提供了任何众多光景所需的API,能够自动学习下这几个API
enterproxy

闲聊并发与相互

并发大家常常提起之,不管是web
server,app并发无处不在,操作系统中,指贰个岁月段中多少个程序处于已经起步运维到甘休之间,且那多少个程序都以在同样处理机上运维,并且任叁个时日点唯有3个程序在处理机上运转。繁多网站都有出现连接数量的范围,所以当呼吁发送太快的时候会导致重临值为空或报错。更有甚者,有个别网址可能因为您发出的面世连接数量过多而当你是在恶意请求,封掉你的ip。

争执于并发,并行大概目生了无数,并行指一组先后按独创新步的快慢实行,不等于时间上的交汇(同三个整日爆发),通过扩张cpu宗旨来完毕四个程序(任务)的同时实行。没有错,并行做到了多职务的还要开始展览

应用async调整并发数量

1经我们有3十四个请求需求发出,诸多网址恐怕会因为您生出的面世连接数太多而当你是在恶意请求,把您的IP封掉。
由此我们总是要求调节并发数量,然后稳步抓取完那3捌个链接。

选取async中mapLimit调控3次性并发数量为五,一回性只抓取6个链接。

 async.mapLimit(arr, 5, function (url, callback) {
      // something
    }, function (error, result) {
      console.log("result: ")
      console.log(result);
    })

咱俩先是应当知道哪些是并发,为啥必要限制并发数量,都有怎么样处理方案。然后就能够去文书档案具体看一下API怎么着运用。async文档能够很好的就学那一个语法。

仿照一组数据,那里再次来到的多少是假的,重返的延时是随机的。

var concurreyCount = 0;
var fetchUrl = function(url,callback){
    // delay 的值在 2000 以内,是个随机的整数 模拟延时
    var delay =  parseInt((Math.random()* 10000000) % 2000,10);
    concurreyCount++;
    console.log('现在并发数是 ' , concurreyCount , ' 正在抓取的是' , url , ' 耗时' + delay + '毫秒');
    setTimeout(function(){
        concurreyCount--;
        callback(null,url + ' html content');
    },delay);
}

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

下一场大家运用async.mapLimit来并发抓取,并得到结果。

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

模仿摘自alsotang

运维输出后获取以下结果

Node.js 1

咱俩发现,并发数从一起先加强,不过增进到5时,就不在扩张。然有职责时就持续抓取,并发连接数量一贯调控在多少个。

Node.js,姣好node简易爬虫系统

因为alsotang前辈的《node包教不包会》学科例子中利用的eventproxy调节的出现数量,大家就来实现三个选拔async调整并发数量的node简易爬虫。

爬取的指标正是本站首页(手动护脸)

首先步,首先大家必要利用以下的模块:

  • url : 用于url解析,那里运用url.resolve()调换1个官方的域名
  • async : 二个实用的模块,提供了强劲的意义和异步JavaScript工作
  • cheerio : 为服务器尤其定制的,连忙,灵活,实行的jQuery宗旨达成
  • superagent : nodejs里1个老大便利的客户端请求代理模块

    通过npm设置依赖模块

Node.js 2

其次步,通过require引进依赖模块,分明爬取对象UTiguanL:

var url = require("url");
var async = require("async");
var cheerio = require("cheerio");
var superagent = require("superagent");

var baseUrl = 'http://www.chenqaq.com';

其三步:使用superagent请求目的U汉兰达L,并行使cheerio处理baseUrl获得指标内容url,并保存在数组arr中

superagent.get(baseUrl)
  .end(function (err, res) {
    if (err) {
      return console.error(err);
    }
    var arr = [];
    var $ = cheerio.load(res.text);
    // 下面和jQuery操作是一样一样的..
    $(".post-list .post-title-link").each(function (idx, element) {
      $element = $(element);
      var _url = url.resolve(baseUrl, $element.attr("href"));
      arr.push(_url);
    });

    // 验证得到的所有文章链接集合
    output(arr);
    // 第四步:接下来遍历arr,解析每一个页面需要的信息

})

我们要求1个函数验证抓取的url对象,很简短咱们只供给二个函数遍历arr并打字与印刷出来就能够:

function output(arr){
    for(var i = 0;i<arr.length;i++){
        console.log(arr[i]);
    }
}

第四步:大家必要遍历得到的UCR-VL对象,解析每3个页面需求的新闻。

此间就必要运用async操纵并发数量,假设您上一步获取了二个小幅度的arr数组,有四个url需求请求,假诺还要爆发多个请求,一些网址就也许会把你的一举一动看成恶意请求而封掉你的ip

async.mapLimit(arr,3,function(url,callback){
    superagent.get(url)
        .end(function(err,mes){
            if(err){
                console.error(err);
                console.log('message info ' + JSON.stringify(mes));
            }
            console.log('「fetch」' + url + ' successful!');
            var $ = cheerio.load(mes.text);
            var jsonData = {
                title:$('.post-card-title').text().trim(),
                href: url,
            };
            callback(null,jsonData);
        },function(error,results){
            console.log('results ');
            console.log(results);
        })
    })

赢得上一步保存url地址的数组arr,限制最大出现数量为三,然后用一个回调函数处理
「该回调函数相比奇特,在iteratee方法中势需要调用该回调函数,有三种情势」

  • callback(null) 调用成功
  • callback(null,data) 调用成功,并且重回数据data追加到results
  • callback(data) 调用失败,不会再持续循环,直接到最后的callback

好了,到那里大家的node简易的小爬虫就完了了,来看望效果呢

Node.js 3

喂呀,首页数据好少,然则成功了呢。