async,node.js是一个流程控制库。
- async.series串行执行一组函数,第一个参数是一个由函数组成的数组或json,第二个参数是回调函数。回调函数里先执行task1的返回结果,再处理task2的。
task1一旦出错,task2不执行。依次输出task1,task2的result。
var async = require("async"); var fs = require("fs"); async.series([ //task1 function(callback){ fs.readFile("test.txt",function(err,data){ callback(err,data) }); }, //task2 function(callback){ fs.readFile("test2.txt",function(err,data){ callback(err,data) }); } ],function(err, results) { console.log(results.toString()); });
2. async.waterfall和series函数有很多相似之处,都是按顺序依次执行一组函数,不同之处是waterfall每个函数产生的值,都将传给下一个函数,task1的result作为参数传给task2 。只输出task2的result
var async = require(‘async‘); async.waterfall([ //task1 function(callback){ callback(‘test‘,1); }, //task2 function(data,callback){ callback(null,2); } ],function(err,results){ console.log(err); //test });
3. async.parallel函数是并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。 传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序
var async=require("async"); async.parallel([ function(callback){ setTimeout(function(){ callback(null, ‘one‘) },5000); }, function(callback){ setTimeout(function(){ callback(null, ‘two‘) },1000); } ], function(err, results){ console.log(results);// one two });
4. async.parallelLimit函数和parallel类似,但是它多了一个参数limit。 limit参数限制任务只能同时并发一定数量,而不是无限制并发
var async=require("async"); async.parallelLimit([ function(callback){ setTimeout(function(){ callback(null, ‘one‘); }, 1000); }, function(callback){ setTimeout(function(){ callback(null, ‘two‘); }, 1000); } ], 1,//限制最多只能并行执行一个任务 function(err, results){ console.log(results);//执行完耗时2s });
5.async.whilst(test,fn,callback) 相当于while,用于循环执行一个函数,只有第一次执行完才会执行下一次,test参数是一个返回布尔值得函数,为真则循环继续。
var count = 0; async.whilst( function () { return count < 5; }, function (callback) { count++; setTimeout(callback, 1000); }, function (err) { } );
6 async.dowhilst(fn,test,callback) 相当于dowhile,也是用于循环,先执行函数,再进行判断,不BB,看例子
var count = 0; async.doWhilst( function (callback) { count++; setTimeout(function(){ callback(null,1);}, 1000); }, function () { return count < 5; }, function (err) { } );
7.async.forever(fn,callback) 跟它名字一样,fn一直循环执行,直到程序出现异常,例子中a=10时,停止循环
var a =0; async.forever( function(callback) { setTimeout(function(){ console.log(a++); if(a==10){ callback(‘err‘,0); }else{ callback(null,1); } },1000) }, function(err) { // } );
8.async.compose(fn1,fn2,fn3...)可以创建一个异步函数的集合函数,将传入的多个异步函数包含在其中,当我们执行这个集合函数时,会依次执行每一个异步函数,返回值作为参数传给下个函数。我们可以使用compose把异步函数f、g、h,组合成f(g(h()))的形式,通过callback得到返回值
function fn1(n, callback) { setTimeout(function () { callback(null, n + 1); }, 1000); } function fn2(n, callback) { setTimeout(function () { callback(null, n * 3); }, 1000); } var demo = async.compose(fn2, fn1);//先执行fn1 demo(4, function (err, result) { console.log(result);//15 });
9. async.auto(tasks,[callback]) 用来处理有依赖关系的多个任务的执行,看官网的例子
async.auto({ get_data: function(callback){ console.log(‘in get_data‘); callback(null, ‘data‘, ‘converted to array‘); }, make_folder: function(callback){ console.log(‘in make_folder‘); callback(null, ‘folder‘); }, write_file: [‘get_data‘, ‘make_folder‘, function(callback, results){ console.log(‘in write_file‘, JSON.stringify(results)); callback(null, ‘filename‘); }], email_link: [‘write_file‘, function(callback, results){ console.log(‘in email_link‘, JSON.stringify(results)); write_file. callback(null, {‘file‘:results.write_file, ‘email‘:‘[email protected]‘}); }] }, function(err, results) { console.log(‘err = ‘, err); console.log(‘results = ‘, results); }); //执行结果 in get_data in make_folder in write_file {"get_data":["data","converted to array"],"make_folder":"folder"} in email_link {"get_data":["data","converted to array"],"make_folder":"folder","write_file":"filename"} err = null results = { get_data: [ ‘data‘, ‘converted to array‘ ], make_folder: ‘folder‘, write_file: ‘filename‘, email_link: { file: ‘filename‘, email: ‘[email protected]‘ } }
8.async.queue(work,concurrency)和parallelLimit类似,多个点可供回调,如无等候任务时(empty)、全部执行完时(drain)等。
var q = async.queue(function(task, callback) { console.log(‘worker is processing task: ‘, task.name); callback(); }, 2); q.push({name: ‘foo‘}, function (err) { console.log(‘finished processing foo‘); }); q.push({name: ‘bar‘}, function (err) { console.log(‘finished processing bar‘); }); //当最后一个任务交给worker执行时,会调用empty函数: q.empty = function() { console.log(‘no more tasks wating‘); }
9.async.iterator (tasks) 将一组函数包装成为一个iterator,可通过next()得到以下一个函数为起点的新的iterator。该函数通常由async在内部使用,但如果需要时,也可在我们的代码中使用它。
var iter = async.iterator([ function() { console.log(‘111‘)}, function() { console.log(‘222‘) }, function() { console.log(‘333‘) } ]); var iter2 = iter();//111 var aa = iter2.next(); aa();//333
10. async.apply() 可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数
var test = function(n, callback, timeout) { timeout = timeout || 200; setTimeout(function() { callback(null, n+1); }, timeout); }; var x = async.apply(test , 1); x(function(err, n){ console.log(n); });
async.parallel([ async.apply(fn1, 3), async.apply(fn2, 100) ], function (err, results) { log(‘err: ‘, err); log(‘results: ‘, results); });