node 使用 async 控制并發(fā)的方法
目標(biāo)
建立一個(gè) lesson5 項(xiàng)目,在其中編寫代碼。
代碼的入口是 app.js,當(dāng)調(diào)用 node app.js 時(shí),它會輸出 CNode(https://cnodejs.org/ ) 社區(qū)首頁的所有主題的標(biāo)題,鏈接和第一條評論,以 json 的格式。
注意:與上節(jié)課不同,并發(fā)連接數(shù)需要控制在 5 個(gè)。
輸出示例:
[ { "title": "【公告】發(fā)招聘帖的同學(xué)留意一下這里", "href": "http://cnodejs.org/topic/541ed2d05e28155f24676a12", "comment1": "呵呵呵呵" }, { "title": "發(fā)布一款 Sublime Text 下的 JavaScript 語法高亮插件", "href": "http://cnodejs.org/topic/54207e2efffeb6de3d61f68f", "comment1": "沙發(fā)!" } ]
知識點(diǎn)
學(xué)習(xí) async(https://github.com/caolan/async ) 的使用。這里有個(gè)詳細(xì)的 async demo 演示:https://github.com/alsotang/async_demo
學(xué)習(xí)使用 async 來控制并發(fā)連接數(shù)。
課程內(nèi)容
lesson4 的代碼其實(shí)是不完美的。為什么這么說,是因?yàn)樵?lesson4 中,我們一次性發(fā)了 40 個(gè)并發(fā)請求出去,要知道,除去 CNode 的話,別的網(wǎng)站有可能會因?yàn)槟惆l(fā)出的并發(fā)連接數(shù)太多而當(dāng)你是在惡意請求,把你的 IP 封掉。
我們在寫爬蟲的時(shí)候,如果有 1000 個(gè)鏈接要去爬,那么不可能同時(shí)發(fā)出 1000 個(gè)并發(fā)鏈接出去對不對?我們需要控制一下并發(fā)的數(shù)量,比如并發(fā) 10 個(gè)就好,然后慢慢抓完這 1000 個(gè)鏈接。
用 async 來做這件事很簡單。
這次我們要介紹的是 async 的 mapLimit(arr, limit, iterator, callback)
接口。另外,還有個(gè)常用的控制并發(fā)連接數(shù)的接口是 queue(worker, concurrency),
大家可以去 https://github.com/caolan/async#queueworker-concurrency 看看說明。
這回我就不帶大家爬網(wǎng)站了,我們來專注知識點(diǎn):并發(fā)連接數(shù)控制。
對了,還有個(gè)問題是,什么時(shí)候用 eventproxy,什么時(shí)候使用 async 呢?它們不都是用來做異步流程控制的嗎?
我的答案是:
當(dāng)你需要去多個(gè)源(一般是小于 10 個(gè))匯總數(shù)據(jù)的時(shí)候,用 eventproxy 方便;當(dāng)你需要用到隊(duì)列,需要控制并發(fā)數(shù),或者你喜歡函數(shù)式編程思維時(shí),使用 async。大部分場景是前者,所以我個(gè)人大部分時(shí)間是用 eventproxy 的。
正題開始。
首先,我們偽造一個(gè) fetchUrl(url, callback)
函數(shù),這個(gè)函數(shù)的作用就是,當(dāng)你通過
fetchUrl('http://www.baidu.com', function (err, content) { // do something with `content` });
調(diào)用它時(shí),它會返回 http://www.baidu.com 的頁面內(nèi)容回來。
當(dāng)然,我們這里的返回內(nèi)容是假的,返回延時(shí)是隨機(jī)的。并且在它被調(diào)用時(shí),會告訴你它現(xiàn)在一共被多少個(gè)地方并發(fā)調(diào)用著。
// 并發(fā)連接數(shù)的計(jì)數(shù)器 var concurrencyCount = 0; 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--; callback(null, url + ' html content'); }, delay); };
我們接著來偽造一組鏈接
var urls = []; for(var i = 0; i < 30; i++) { urls.push('http://datasource_' + i); }
這組鏈接的長這樣:
接著,我們使用 async.mapLimit 來并發(fā)抓取,并獲取結(jié)果。
async.mapLimit(urls, 5, function (url, callback) { fetchUrl(url, callback); }, function (err, result) { console.log('final:'); console.log(result); });
運(yùn)行輸出是這樣的:
可以看到,一開始,并發(fā)鏈接數(shù)是從 1 開始增長的,增長到 5 時(shí),就不再增加。當(dāng)其中有任務(wù)完成時(shí),再繼續(xù)抓取。并發(fā)連接數(shù)始終控制在 5 個(gè)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解Node.js中的Async和Await函數(shù)
- Node.js 中使用 async 函數(shù)的方法
- 淺析node Async異步處理模塊用例分析及常用方法介紹
- nodejs async異步常用函數(shù)總結(jié)(推薦)
- 在 Node.js 中使用 async 函數(shù)的方法
- NodeJs通過async/await處理異步的方法
- 深入學(xué)習(xí)nodejs中的async模塊的使用方法
- async/await與promise(nodejs中的異步操作問題)
- 從零學(xué)習(xí)node.js之詳解異步控制工具async(八)
- 淺談node.js中async異步編程
相關(guān)文章
使用 Node.js 模擬滑動拼圖驗(yàn)證碼操作的示例代碼
本篇文章主要介紹了使用 Node.js 模擬滑動驗(yàn)證碼操作的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11Node.js使用Koa搭建 基礎(chǔ)項(xiàng)目
時(shí)下前端工程師有很多人比較關(guān)注NodeJs以及express 框架或者Koa 框架之類的新技術(shù)。難得我最近閑時(shí)較多,利用一下舊歷新年尚未正式到來的這片閑暇,也來涉足其中,一窺其中奧妙。2018-01-01Node.js調(diào)用java之node-java問題
這篇文章主要介紹了Node.js調(diào)用java之node-java問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10npm 更改默認(rèn)全局路徑以及國內(nèi)鏡像的方法
今天小編就為大家分享一篇npm 更改默認(rèn)全局路徑以及國內(nèi)鏡像的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05