nodejs 并发控制
生活随笔
收集整理的這篇文章主要介紹了
nodejs 并发控制
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.用 eventproxy 實(shí)現(xiàn)控制并發(fā):
var EventProxy = require('eventproxy');
const most = 5;//并發(fā)數(shù)5
var urllist = [....];//待抓取url列表,100個(gè)
function foo(start){
var ep = new EventProxy();
ep.after('ok',most,function(){
foo(start+most);//一個(gè)批次任務(wù)完成,遞歸進(jìn)行下一批任務(wù)
});
var q=0;
for(var i=start;i<urllist.length;i++){
if(q>=most){
break;//最多添加most個(gè)任務(wù)
}
http.get(urllist[i],function(res){
//....
res.on('end',function(){
ep.emit('ok');//一個(gè)任務(wù)完成,觸發(fā)一次ok事件
});
});
q++;
}
}
foo(0);
2.使用async.mapLimit 控制并發(fā)
var async = require('async');
//模擬一組連接地址
var urls = [];
for(var i = 0; i < 30; i++) {
urls.push('http://datasource_' + i);
}
console.log(urls);
// 并發(fā)連接數(shù)的計(jì)數(shù)器
var concurrencyCount = 0;
// 并發(fā)抓取數(shù)據(jù)的過程
var fetchUrl = function (url, callback) {
// delay 的值在 2000 以內(nèi),是個(gè)隨機(jī)的整數(shù)
var delay = parseInt((Math.random() * 10000000) % 2000, 10);
concurrencyCount++;
console.log('現(xiàn)在的并發(fā)數(shù)是', concurrencyCount, ',正在抓取的是', url, ',耗時(shí)' + delay + '毫秒');
setTimeout(function () {
concurrencyCount--;
//抓取成功,調(diào)用回調(diào)函數(shù)
callback(null, url + ' html content');
}, delay);
};
//使用 async.mapLimit 來 5 個(gè)并發(fā)抓取,并獲取結(jié)果
async.mapLimit(urls, 5, function (url, callback) {
fetchUrl(url, callback);
}, function (err, result) {
//所有連接抓取成功,返回回調(diào)結(jié)果列表
console.log('final:');
console.log(result);
});
3.async.queue 非常合適用來控制并發(fā)
/**
* Created by admin on 16/3/20.
*/
"use strict"
var http = require('http');
var cheerio = require('cheerio');
var URL = require('url');
var path = require('path');
var fs = require('fs');
var async = require('async');
var baseUrl = "http://cnodejs.org/";
var targetUrl = "http://cnodejs.org/";
var stime = new Date();
function sGet(url,callback){
var chunks = [];
http.get(url,(res)=>{
if (res.statusCode != '200') {
callback({message:"抓取失敗,狀態(tài)碼:"+res.statusCode,url:url});
return;
}
res.on('data',(chunk)=>{
chunks.push(chunk);
});
res.on('end',()=>{
callback(null,Buffer.concat(chunks).toString());
});
}).on('error',(e)=>{
callback({message:"抓取失敗",url:url,err:e});
});
}
sGet(targetUrl,(err,data)=>{
if (err) {
console.log(err);
return false;
}
var $ = cheerio.load(data);
var anchors = $("#topic_list a.topic_title");
console.log('共'+anchors.length+'個(gè)任務(wù)');
const most=5;//并發(fā)數(shù)
//創(chuàng)建隊(duì)列并指定并發(fā)數(shù)
var q=async.queue(function(url,callback){
var filename = path.basename(url)+'.txt';
sGet(url, (err, data)=> {
if (err) {
callback(err);
return false;
}
fs.writeFile('./html/' + filename, data, function (err) {
if (err) {
throw err;
}
callback(null,filename);
});
});
},most);
q.drain = function() {
console.log('任務(wù)全部完成,共耗時(shí):'+(new Date()-stime)+'ms');
}
anchors.each(function(){
var url = URL.resolve(baseUrl,$(this).attr('href'));
q.push(url,function(err,filename){
if (err) {
console.log(err);
return;
}
console.log("finished:"+filename);
});
});
});
總結(jié)
以上是生活随笔為你收集整理的nodejs 并发控制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 引导程序修复工具,linux
- 下一篇: 第13周-网络