半懶的狀態去寫了只小爬蟲,想把其他網站的視頻爬下來傳到其他服務器上,沒想到搞了兩天,Nodejs的異步機制真是讓人又愛又恨。。
異步機制導致的問題
當前遇到nodejs的異步機制最大的問題是跟循環配合一起使用的時候,循環會一下併發所有的函數,舉個例子
// 抓取單個視頻並添加水印,上傳數據庫等操作
function getId(id) { ... }
// 抓取id爲0 - 4000的視頻
for(var id = 0;id <= 4000;++ id) {
getId(id);
}
這樣會一下子將幾千個請求同時發送出去,造成後面的請求無響應,本地loading過高,服務器還可能會封ip等嚴重後果。
最終解決方案
最後的解決方案,用的是async.mapLimit
,
var ids = [];
for(var id = 0;id <= 10000;id ++) {
ids.push(id);
}
var async = require('async');
async.mapLimit(ids,1, function(id,spCallback) {
getId(id,spCallback);
});
async的文檔
(忍不住想吐槽下nodejs相關的文檔,對新手一點也不友好。。或者是我我太弱了!?)
github:@caolan/async
官方文檔:http://caolan.github.io/async/
mapLimit接口描述這裏