在實作爬蟲專案時,有時候需要連續發幾個HTTP request到server端請求資料(比方搜尋頁數較多時),我直覺想到的是這樣的做法:
同時發送所有request, 等全部的request完成再進行下個步驟
一次發送 5 個請求可能沒什麼問題,不過當請求數量變大,你很可能會遇到這個報錯 Error: read ECONNRESET
原因是因為Node沒有辦法一次處理太多請求。
解決辦法
使用Bluebird Promise.map
設定 concurrency:原先使用的Promise.all並沒有設定處理事件的上限,也就是說假設放了100個item在Promise.all裡面,這100個item會同時啟動。這時候可以使用Bluebird幫我們達成任務。
Bluebird是一個第三方的promise庫,它相容原本的promise物件,並提供額外的擴充功能。
我們要使用的就是其中的 promise.map,官方文件的操作方法如下:
Promise.map(
Iterable<any>|Promise<Iterable<any>> input,
function(any item, int index, int length) mapper,
[Object {concurrency: int=Infinity} options]
) -> Promise
第一個參數放可迭代的對象,第二個參數放callback function,第三個參數放concurrency,也就是一次要運行的promise數量
這樣的寫法就可以控制一次發送request的數量,避免連線中斷或是造成他人伺服器的負荷。
其它作法
使用 es6-promise-pool或是 promise-limit 也可以達到類似的效果
參考文章
以上就是本次除錯的紀錄,如果文章有任何錯誤或反饋歡迎留言告訴我!