node的非同步io雖然好用,但是控制非同步流程確實一個比較麻煩的事情,比如在爬蟲中控制併發數量,避免併發過大導致網站宕機或被加入黑名單。因此需要一個工具來控制併發,這個工具可以自己寫或者使用async(官方文檔點擊這裡)。代碼基於node 8.x,如版本過低可能會出現錯誤。 說明 async本身有七十 ...
node的非同步io雖然好用,但是控制非同步流程確實一個比較麻煩的事情,比如在爬蟲中控制併發數量,避免併發過大導致網站宕機或被加入黑名單。因此需要一個工具來控制併發,這個工具可以自己寫或者使用async(官方文檔點擊這裡)。代碼基於node 8.x,如版本過低可能會出現錯誤。
說明
async本身有七十多個方法,這裡只說明幾個比較常用的簡單函數用法,想進一步學習可參考文檔。總的來說分為兩大類。
一、第一個參數為函數集合,也就是遍歷執行集合中的函數。
1.順序執行 series(tasks , function(err,res){ })
tasks為函數數組,數組中的每一項都為待執行函數。
a.下麵是一個最簡單示例,待執行函數為非非同步
1 const asyncx = require( 'async' ); 2 3 let tasks = []; 4 for( let i = 0 ; i < 10 ; i++ ) 5 { 6 tasks.push( 7 function( callback ){ 8 //dosomething 9 console.log( i ); 10 //本函數用來通知async本次任務完成情況,並把結果帶出去。 11 callback( null , i ); //第一個參數為異常參數,如果傳入一個error( 比如new Error('error') ),併發結束,調用series里的回調。 12 } 13 ) 14 } 15 asyncx.series( tasks , function(err , res ){ 16 if( err ) 17 console.log( err ); 18 console.log( res ); 19 } )
運行結果
b.待執行函數為非同步
如果待處理的函數也是非同步函數可將callback參數傳入到非同步函數中,在真正結束的時候調用callback。
1 const asyncx = require( 'async' ); //模塊命名為asyncx避免和es7中的async/await衝突 2 3 let tasks = []; 4 for( let i = 0 ; i < 10 ; i++ ) 5 { 6 tasks.push( 7 function( callback ){ 8 setTimeout( function(){ 9 console.log(i); 10 callback( null , 1 ); //在這裡整個處理才是真正完成,然後調用callback通知async本任務結束 11 } , 2000 ); 12 } 13 ) 14 } 15 asyncx.series( tasks , function(err , res ){ 16 if( err ) 17 console.log( err ); 18 console.log( res ); 19 } )
如果想要在任務中使用es7的async/await 可將待處理代碼放在一個閉包中(直接在function前加async會報錯),下麵示例。
1 const asyncx = require( 'async' ); //模塊命名為asyncx避免和es7中的async/await衝突 2 3 let tasks = []; 4 for( let i = 0 ; i < 10 ; i++ ) 5 { 6 tasks.push( 7 function( callback ){ 8 (async function(){ 9 let sum = await doSomething( i ); 10 callback( null , sum ); 11 })(); 12 } 13 ) 14 } 15 16 async function doSomething( i ){ 17 return new Promise( function( resolve , reject ){ 18 setTimeout(function(){ 19 console.log( i ); 20 resolve( i ); 21 } , 1000 ); 22 } ); 23 } 24 25 asyncx.series( tasks , function(err , res ){ 26 if( err ) 27 console.log( err ); 28 console.log( res ); 29 } )
2.併發執行 parallel( tasks , function(err,res){} )
參數如上,不限制併發
3.併發限制執行parallelLimit( tasks , num , function(err,res){} )
參數同上,num為最大併發數量
二、第一個參數為非函數集合。
比如
async.map(['file1','file2','file3'], function(item,callback){ //dosomething callback( null , 'done' ); }, function(err, results) { // results is now an array of stats for each file });
第二個參數為一個非同步函數,要能接受兩個參數item(前面集合中的一項),callback 通知async任務完成
還有其他的函數用法都是類似只是具體作用不一樣。可參考官方文檔說明。