async
和eventproxy
同樣都是控制并發(fā)的,eventproxy
會(huì)同時(shí)發(fā)起所有請(qǐng)求,所以在上一篇博客中最后出現(xiàn)了503
的錯(cuò)誤;使用async
則可以很好地解決這個(gè)問題,使用async
能夠控制并發(fā)線程的數(shù)量
一、async
- async在github : https://github.com/caolan/async
- async使用示例 : https://github.com/alsotang/async_demo
- async常用的方法有好幾個(gè),這里使用新增加的
mapLimit(collection,iteratee(item,callback),callback(err,results))
方法解決遺留的問題
二、使用async限制并發(fā)訪問數(shù)量
1. demo
首先來個(gè)預(yù)熱程序看看如何使用mapList方法:
var async=require("async");
var currentCount=0;
console.log("will create a url list size 10 !");
var urls=[];
for(var i=0;i<10;i++){
urls.push('http://www.example.com/'+i+".html");
}
async.mapLimit(urls,2,function(url,callback){
var delay=parseInt(500);
currentCount++;
console.log("currentCount is :"+currentCount+",current url is :"+url+",use time is :"+delay+" mm");
setTimeout(function(){
currentCount--;
callback(null,url+' html content ');
},delay);
},function(err,result){
console.log("result:");
console.log(result);
});
運(yùn)行結(jié)果:
will create a url list size 10 !
currentCount is :1,current url is :http://www.example.com/0.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/1.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/2.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/3.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/4.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/5.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/6.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/7.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/8.html,use time is :500 mm
currentCount is :2,current url is :http://www.example.com/9.html,use time is :500 mm
result:
[ 'http://www.example.com/0.html html content ',
'http://www.example.com/1.html html content ',
'http://www.example.com/2.html html content ',
'http://www.example.com/3.html html content ',
'http://www.example.com/4.html html content ',
'http://www.example.com/5.html html content ',
'http://www.example.com/6.html html content ',
'http://www.example.com/7.html html content ',
'http://www.example.com/8.html html content ',
'http://www.example.com/9.html html content ' ]
2.mapLimit方法參數(shù)的含義說明
mapLimit方法的完整定義:
mapLimit(collection,iteratee(item,callback),callback(err,results))
collection : 一個(gè)數(shù)組
item : collection的一個(gè)元素
callback : 回調(diào)函數(shù),該回調(diào)函數(shù)比較特殊,理解起來也比較困難,在iteratee方法中一定要調(diào)用該回調(diào)函數(shù),一般來說會(huì)有三種常用的使用方法:
使用方法形式 | 意義 |
---|---|
callback(null) | 調(diào)用成功 |
callback(null,data) | 調(diào)用成功,并且返回?cái)?shù)據(jù)data追加到results |
callback(data) | 調(diào)用失敗,不會(huì)再繼續(xù)循環(huán),直接到最后的callback |
3.使用async限制并發(fā)訪問數(shù)量完整代碼
var express=require("express");
var superagent=require("superagent");
var cheerio=require("cheerio");
var url=require("url");
var eventproxy=require("eventproxy");
var async=require("async");
var app=express();
var baseUrl='https://cnodejs.org/';
function output(arr){
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
}
superagent.get(baseUrl).end(function(err,resp){
if(err){
return console.error(err);
}
var arr=[];
var $=cheerio.load(resp.text);
$("#topic_list .topic_title").each(function(idx,element){
$element=$(element);
var _url=url.resolve(baseUrl,$element.attr("href"));
arr.push(_url);
});
//驗(yàn)證得到的所有文章鏈接集合
output(arr);
//接下來遍歷arr,解析每一個(gè)頁面中需要的信息
async.mapLimit(arr,3,function(url,callback){
superagent.get(url).end(function(err,mes){
if(err){
console.log("get \""+url+"\" error !"+err);
console.log("message info:"+JSON.stringify(mes));
}
console.log('fetch '+url+" succeful !");
//console.log("mess info:"+JSON.stringify(mes));
var $=cheerio.load(mes.text);
var jsonData={
title:$(".topic_full_title").text().trim(),
href:url,
firstcomment:$("#reply1 .markdown-text").text().trim()
};
console.log("aim data is :"+JSON.stringify(jsonData));
callback(null,jsonData);
});
},function(error,results){
console.log("result :");
console.log(results);
});
});
這樣上一篇博客中的503錯(cuò)誤就解決了。