網上有一篇async.js的文章,但是看完后一頭霧水,里面很多錯誤,只好學習下官方的文檔
官方的文檔分為三個模塊:
1.Collections 集合
2.Control Flow 控制流程
3.Utils 公共模塊
最常用的應該就是第二個模塊了,async的主要功能也都集中在里面
Control Flow
1.series(tasks, [callback]) 順序執行數組、集合內的函數,當前面一個函數執行完成就會立即執行下一個函數,如果函數觸發了錯誤,可以在callback函數中驗證,否則會一直執行完成tasks
1 async.series([ 2 function(callback){ 3 // do some stuff ... 4 callback(null, 'one'); 5 }, 6 function(callback){ 7 // do some more stuff ... 8 callback(null, 'two'); 9 } 10 ], 11 // optional callback 12 function(err, results){ 13 // results is now equal to ['one', 'two'] 14 }); 15 16 17 // an example using an object instead of an array 18 async.series({ 19 one: function(callback){ 20 setTimeout(function(){ 21 callback(null, 1); 22 }, 200); 23 }, 24 two: function(callback){ 25 setTimeout(function(){ 26 callback(null, 2); 27 }, 100); 28 } 29 }, 30 function(err, results) { 31 // results is now equal to: {one: 1, two: 2} 32 });
2.parallel(tasks, [callback]) 並行執行數組、集合內的方法,不用等到前一個函數執行完再執行下一個函數,如果函數觸發了錯誤,可以在callback函數中驗證
1 async.parallel([ 2 function(callback){ 3 setTimeout(function(){ 4 callback(null, 'one'); 5 }, 200); 6 }, 7 function(callback){ 8 setTimeout(function(){ 9 callback(null, 'two'); 10 }, 100); 11 } 12 ], 13 // optional callback 14 function(err, results){ 15 // the results array will equal ['one','two'] even though 16 // the second function had a shorter timeout. 17 }); 18 19 20 // an example using an object instead of an array 21 async.parallel({ 22 one: function(callback){ 23 setTimeout(function(){ 24 callback(null, 1); 25 }, 200); 26 }, 27 two: function(callback){ 28 setTimeout(function(){ 29 callback(null, 2); 30 }, 100); 31 } 32 }, 33 function(err, results) { 34 // results is now equals to: {one: 1, two: 2} 35 });
3.parallelLimit(tasks, limit, [callback]) 和2用法一樣,只是多了一個任務數量限制,最多允許多少個任務在並行執行
4.whilst(test, fn, callback) 等同於while的用法,第一個參數為驗證條件,第二個參數為執行函數,第三個參數為驗證失敗后回調函數,一般在做延遲動畫用的比較多
1 var count = 0; 2 3 async.whilst( 4 function () { return count < 5; },//驗證成功繼續,失敗進回調 5 function (callback) { 6 count++; 7 setTimeout(callback, 1000); 8 }, 9 function (err) { 10 // 5 seconds have passed 11 } 12 );
5.waterfall(tasks, [callback]) tasks依次運行,前一個函數的回調會作為后一個函數的參數,如果有任何任務通過一個錯誤的回調,下一個函數不執行
1 async.waterfall([ 2 function(callback){ 3 callback(null, 'one', 'two'); 4 }, 5 function(arg1, arg2, callback){ 6 // arg1 now equals 'one' and arg2 now equals 'two' 7 callback(null, 'three'); 8 }, 9 function(arg1, callback){ 10 // arg1 now equals 'three' 11 callback(null, 'done'); 12 } 13 ], function (err, result) { 14 // result now equals 'done' 15 });
貼上一個mongodb連接數據庫的例子
1 async.waterfall([ 2 function(cb){ 3 //打開數據庫 4 mongodb.open(function(err,db){ 5 cb(err,db); 6 }); 7 }, 8 function(db, cb){ 9 //實例化posts表 10 db.collection('posts',function(err,collection){ 11 cb(err, collection); 12 }); 13 }, 14 function(collection, cb){ 15 //通過用戶名、時間及標題查找文檔,並把一條留言對象添加到該文檔的 comments 數組里 16 collection.update({ 17 "name": name, 18 "time.day": day, 19 "title": title 20 }, { 21 $push: {"comments": comment} 22 } , function (err) { 23 cb(err); 24 }); 25 } 26 ],function(err){ 27 mongodb.close(); 28 err ? callback(err) : callback(null);//callback為此函數執行完成的回調方法,用戶自定義方法 29 });
waterfall主要用來解決回調嵌套回調的方法,如果回調嵌套超過2級就可以考慮使用waterfall,下面就是回調嵌套的一個示例
1 //打開數據庫 2 mongodb.open(function (err, db) { 3 if (err) { 4 return callback(err); 5 } 6 //讀取 posts 集合 7 db.collection('posts', function (err, collection) { 8 if (err) { 9 mongodb.close(); 10 return callback(err); 11 } 12 //根據用戶名、發表日期及文章名進行查詢 13 collection.findOne({ 14 "name": name, 15 "time.day": day, 16 "title": title 17 }, function (err, doc) { 18 mongodb.close(); 19 if (err) { 20 return callback(err); 21 } 22 callback(null, doc);//返回查詢的一篇文章(markdown 格式) 23 }); 24 }); 25 });
6.compose(fn1, fn2...) 按順序加入到隊列中,按順序執行,將上一個函數的結果作為下一個函數的值
1 function add1(n, callback) { 2 setTimeout(function () { 3 callback(null, n + 1); 4 }, 10); 5 } 6 7 function mul3(n, callback) { 8 setTimeout(function () { 9 callback(null, n * 3); 10 }, 10); 11 } 12 13 var add1mul3 = async.compose(mul3, add1); 14 15 add1mul3(4, function (err, result) { 16 // result now equals 15 17 });
更多api請參見:https://github.com/caolan/async#times