知識點
- 學習 async(https://github.com/caolan/async ) 的使用。這里有個詳細的 async demo 演示:https://github.com/alsotang/async_demo
- 學習使用 async 來控制并發(fā)連接數(shù)晃琳。
課程內(nèi)容
使用eventproxy控制并發(fā)(http://www.reibang.com/p/c13a9977053a)的代碼其實是不完美的。為什么這么說人灼,是因為在這個項目之中顾翼,之前我使用的是一次性發(fā)送20個請求出去而簡書因為我發(fā)出的并發(fā)連接數(shù)太多而當你是在惡意請求,雖然并沒有把 IP 封掉适贸,但是出現(xiàn)了503錯誤。所以之后代碼之中選擇了只發(fā)送3個請求烙样。
我們在寫爬蟲的時候蕊肥,如果有 1000 個鏈接要去爬谒获,那么不可能同時發(fā)出 1000 個并發(fā)鏈接出去對不對?我們需要控制一下并發(fā)的數(shù)量裸准,比如并發(fā) 10 個就好赔硫,然后慢慢抓完這 1000 個鏈接。
用 async 來做這件事很簡單爪膊。
這次我們要介紹的是 async 的 mapLimit(arr, limit, iterator, callback)
接口。另外僵芹,還有個常用的控制并發(fā)連接數(shù)的接口是 queue(worker, concurrency)
小槐,大家可以去 https://github.com/caolan/async#queueworker-concurrency 看看說明荷辕。
對了,還有個問題是疮方,什么時候用 eventproxy,什么時候使用 async 呢疆栏?它們不都是用來做異步流程控制的嗎惫谤?
我的答案是:
當你需要去多個源(一般是小于 10 個)匯總數(shù)據(jù)的時候,用 eventproxy 方便溜歪;當你需要用到隊列,需要控制并發(fā)數(shù)蝴猪,或者你喜歡函數(shù)式編程思維時,使用 async嚎莉。大部分場景是前者沛豌,所以我個人大部分時間是用 eventproxy 的。
正題開始。
首先爬早,我們偽造一個 fetchUrl(url, callback)
函數(shù)启妹,這個函數(shù)的作用就是,當你通過
fetchUrl('http://www.baidu.com', function (err, content) {
// do something with `content`
});
調(diào)用它時饶米,它會返回 http://www.baidu.com
的頁面內(nèi)容回來。
當然照瘾,我們這里的返回內(nèi)容是假的丧慈,返回延時是隨機的。并且在它被調(diào)用時逃默,會告訴你它現(xiàn)在一共被多少個地方并發(fā)調(diào)用著。
這組鏈接的長這樣:
運行輸出是這樣的:
可以看到,一開始吟税,并發(fā)鏈接數(shù)是從 1 開始增長的,增長到 5 時肖抱,就不再增加。當其中有任務完成時虐沥,再繼續(xù)抓取泽艘。并發(fā)連接數(shù)始終控制在 5 個。