看看npmjs.org
里的模块依赖排行榜,async
常期排在前三,可见此库确实不错,今天就来简单的说说它的作用
async
是nodejs
里的流程控制模块,也可以用在浏览器端,主要是用来控制多个异步调用时的顺序以及依赖,在不用async
之前,多个异步调用通常是这样的
fs.readFile('file1', function(){
fs.readFile('file2', function(){
fs.readFile('file3', function(){
//.....
})
});
})
当业务比较复杂的时候,异步嵌套将会更深,这样就会形成异步地狱
,这样非常不利于代码维护以及业务处理,而且对异常处理也不方便,下面我们来看看用async
是怎么解决的,当然这种情况用promise
机制来处理也可以,但是今天这里只讲async
.
async.series
串行执行多个异步方法,使嵌套调用扁平化
async.series([
function(callback){
fs.readFile('../data/file.txt', 'utf8', callback);
},
function(callback){
fs.readFile('../data/file1.txt', 'utf8', callback);
}],
function(err, results){
if(err) {
console.log(err)
}else{
console.log(results);
}
});
series
允许传递两个参数,第一个参数代表要异步执行的所有函数,后一个参数是当前面所有异步执行完之后执行的一个回调函数,只要有一个异步方法异步,则直接执行回调函数,err
参数就是异常信息,当所有的异步方法执行成功之后,回调函数里的result
保存的前面所有异步方法执行的结果.
- 注意代码里的
callback
为async
自己传递的固定参数不可更改.
series
是串行执行的,也就是说当异步方法比较多的时候,其实串行执行的效率并不是很高,假如异步方法之前没有依赖关系的话,完全可以并行执行,下面我们来看看async
提供的并行方法
async.parallel
并行执行多个异步方法,并返回多个结果组成的数组
async.parallel([
function(callback){
fs.readFile('../data/file.txt', 'utf8', callback);
},
function(callback){
fs.readFile('../data/file1.txt', 'utf8', callback);
}],
function(err, results){
if(err) {
console.log(err)
}else{
console.log(results);
}
});
parallel
在执行没有依赖关系的异步操作时候,效率还是不错的,回调函数跟上面的series
一样,只要有一个异步方法出现异常,则传递异常信息给回调的第一个参数,都成功则results
返回包含所有结果的数组.
- 注意代码里的
callback
为async
自己传递的固定参数不可更改.
了解了串行和并行的方法之后,有一个问题那就是当后面的异步方法需要前面的异步方法返回的结果作为依赖的时候怎么办呢,async
也提供了这样的方法
async.waterfall
前面异步方法返回的结果作为后面异步方法的条件,依次串行执行异步方法,最后返回最后一个异步方法的结果
async.waterfall([
function(callback){
fs.readFile('../data/file.txt', 'utf8', function(err, content){
callback(err, content);
})
},
function(arg1, callback){
fs.readFile('../data/' + arg1, 'utf8', callback);
}],
function(err, results){
if(err) {
console.log(err)
}else{
console.log(results);
}
})
waterfall
方法就是用来处理异步方法之间的依赖的,这里跟上面的区别在于callback
方法传递了两参数,null
,content
, 第一个参数代表是否异常;第二个参数代码当前异步方法返回的结果,这个值将会作为下一个异步方法的参数,比如这里的function(arg1, callback)
,arg1
参数就是前一个异步方法返回传递的结果,假如后面的异步方法不需要前面的依赖则不用传递这个参数,像上面的第二异步方法那样
- 注意代码里的
callback
为async
自己传递的固定参数不可更改.
当异步方法之前的依赖关系从一对一变到一对多了怎么办呢,上面的方法只有处理一对一的关系,一对多的话则不行,下面来看看async
提供的超级好用的方法auto
async.auto
智能根据配置文件执行异步方法,支持一对多的情况
var deps = {
'file': function(callback){
fs.readFile('../data/file.txt', 'utf8', function(err, content){
callback(err, content); // => file1.txt
});
},
'file1': function(callback){
fs.readFile('../data/file2.txt', 'utf8', function(err, content){
callback(err, content); // => ../data/
});
},
'action': ['file', 'file1', function(callback, result){
fs.readFile(result.file1 + result.file, 'utf8', function(err, content){
callback(err, { result: content, xuwm: 'feenan'});
});
}]
};
async.auto(deps, function(err, result){
console.log(result);
});
auto
方法会根据异步方法里的依赖关系,保证在依赖方法执行完成之后再去执行异步方法,auto
允许传递两个参数,第一个参数是异步方法关系的定义,是一个key-vale方式的键值对,值传递单个函数则表示没有依赖,传递数组的话,数组内前面写上依赖的键值,最后写上异步方法.
- 注意这里的异步方法会依赖前面异步方法返回的结果,所以
callback
会传递两参数,异常和结果
总结
其实async
还有很多别的功能,本身也提供了很多数组相关的操作,更多信息请看这里async git.