在node中各种回调函数各种嵌套,如果嵌套够多,程序十分混乱,可以使用async异步框架来改善
npm install async --save
var async = require('async'); // 加载模块
1、串行方法serial:
// 必须回调,结果在series回调函数中
async.series([
function (callback) {
console.time('cost')
setTimeout(function () {
console.log('f1执行完成')
// 第一个参数为错误对象,第二个为执行结果,会在series执行完成的回调中
callback(null, 'f1');
}, 3000);
}, function (callback) {
setTimeout(function () {
console.log('f2执行完成')
callback(null, 'f2');
}, 2000);
}, function (callback) {
setTimeout(function () {
console.log('f3执行完成')
callback(null, 'f3');
}, 1000);
}], function (err, results) {
console.timeEnd('cost');
console.log(results)
})
结果将耗时6秒钟,即为各个函数耗时总和:cost: 6015ms 、[ 'f1', 'f2', 'f3' ]
2、并行执行parallel:
// 并行执行(多个同时执行)
// 当都执行完成时会回调
// 花费时间为执行所需时间最长的哪个
// 还可以指定同时并发执行的函数数量
// async.parallelLimit(tasks,limit,callback)
async.parallel([
function (callback) {
console.time('cost');
setTimeout(function () {
// 第一个为错误参数,第二个为执行结果
callback(null, 'result1');
}, 3000)
},
function (callback) {
setTimeout(function () {
callback(null, 'result2');
}, 2000)
}
], function (err, results) {
// 本函数为执行所有完成时的回调
console.timeEnd('cost')
console.log(results)
})
多个任何同时执行,耗时取决于耗时最长的任务,结果:cost: 3001ms、[ 'result1', 'result2' ]
3、串行依赖执行waterfall:
下一个任务可以等到上一个任务的执行结果:
// 串行 // 瀑布流方式 // 下一个函数可以取得上一个函数的传递的参数 async.waterfall([ function (callback) { console.time('cost') setTimeout(function () { // 第一个参数为错误信息,第二个参数为传递给下一个函数的参数 console.log('f1') callback(null, 'd1') }, 2000) }, // data为上一个函数传递的参数,callback执行完的回调 function (data, callback) { setTimeout(function () { console.log('参数:' + data) console.log('f2') // 第一个为错误信息,第二个为传递给下一个的参数,如果是最后一个则为结果 callback(null, data + 'd2') }, 2000) } ], function (err, result) { console.timeEnd('cost') console.log('最终结果:' + result) })
结果:类似于串行paralle,但是不同的是waterfull下一个任务可以取得上一个任务的执行结果,lcost: 4002ms、最终结果:d1d2
4、并行串行同时执行,但可以依赖其他任务auto:
// 并行和串行同时,可以依赖某一个函数
async.auto({
task1:function(callback){
// 第一个为错误对象,第二个为传递一个依赖此函数执行结果的函数
callback(null,'task1');
},
task2:function(callback){
// 第一个为错误对象,第二个为传递一个依赖此函数执行结果的函数
callback(null,'task2');
},
// 此任务依赖前两个任务,前两个为并行执行
task3:['task1','task2',function(callback,preresult){
// preresult是锁依赖函数传递的参数
console.log('task3.preresult:'+util.inspect(preresult))
// 第一个为错误对象,第二个为传递一个依赖此函数执行结果的函数
callback(null,'task3');
}],
// 此任务依赖task3任务
task4:['task3',function(callback,preresult){
console.log('task4.preresult:'+util.inspect(preresult));
// 第一个为错误对象,第二个为传递给依赖此任务的参数
callback(null,'task4');
}]
},function(err,results){
if(err){
return console.log(err);
}
console.log(util.inspect(results))
})
结果:{ task1: 'task1', task2: 'task2', task3: 'task3', task4: 'task4' }
5、给函数预置第一个参数apply:
// 相当于给传递的函数预置了第一个参数 // 返回一个新的函数 var retfn = async.apply(console.log,'mylog'); retfn('日志'); retfn('日志');
结果: mylog 日志 mylog 日志 mylog 日志