网上有一篇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