您的位置:首页 > Web前端 > Node.js

nodejs中Async库使用

2014-03-03 10:33 309 查看
“流程控制”本来是件比较简单的事,但是由于Nodejs的异步架构的实现方法,对于需要同步的业务逻辑,实现起来就比较麻烦。嵌套3-4层,代码就会变得的支离破碎了!

现在介绍一个库async ,链接是https://github.com/caolan/async

Async的内容分为三部分:

流程控制:简化十种常见流程的处理
集合处理:如何使用异步操作处理集合中的数据
工具类:几个常用的工具类


series(tasks, [callback]) (多个函数依次执行,之间没有数据交换)

有多个异步函数需要依次调用,一个完成之后才能执行下一个。各函数之间没有数据的交换,仅仅需要保证其执行顺序。这时可使用series。
step1(function(err, v1) {
step2(function(err, v2) {
step3(function(err, v3) {
// do somethig with the err or values v1/v2/v3
}
}
});

从中可以看到这嵌套还是比较多深的,如果再多几步,会更深。

在代码中忽略对了每一层err的处理,否则还都等加上 if(err) return callback(err),那就更麻烦了。

对于这种情况,使用async来处理,在每个step中执行一些操作,这时可写成:

var async = require('async');
async.series([
function(callback){
console.log('step1');
// do some stuff ...
callback(null, 'one');
},
function(callback){
console.log('step2');
// do some more stuff ...
callback(null, 'two');
}
],
function(err, result) {
console.log(result);
// do somethig with the err or values v1/v2/v3
});

返回结果:

step1

step2

['one', 'two']

依次执行一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。

如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且将会立刻会将该error以及已经执行了的函数的结果,传给series中最后那个callback。

当所有的函数执行完后(没有出错),则会把每个函数传给其回调函数的结果合并为一个数组,传给series最后的那个callback。

还可以json的形式来提供tasks。每一个属性都会被当作函数来执行,并且结果也会以json形式传给series最后的那个callback。这种方式可读性更高一些。


parallel(tasks, [callback]) (多个函数并行执行)

并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。

如果某个函数出错,则立刻将err和已经执行完的函数的结果值传给parallel最终的callback。其它未执行完的函数的值不会传到最终数据,但要占个位置。

同时支持json形式的tasks,其最终callback的结果也为json形式。

示例代码:
var async = require('async');
async.parallel([
function(callback){
setTimeout(function(){
console.log('step1');
callback(null, 'one');
}, 200);
},
function(callback){
setTimeout(function(){
console.log('step2');
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results){
console.log(results);
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});
返回结果:

step2

step1

['one', 'two']


waterfall(tasks, [callback]) (多个函数依次执行,且前一个的输出为后一个的输入)这个函数使用非常频繁

与seires相似,按顺序依次执行多个函数。不同之处,每一个函数产生的值,都将传给下一个函数。如果中途出错,后面的函数将不会被执行。错误信息以及之前产生的结果,将传给waterfall最终的callback。

这个函数名为(瀑布),可以想像瀑布从上到下,中途冲过一层层突起的石头。
var async = require('async');
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
console.log(arg1,arg2);
callback(null, 'three');
},
function(arg1, callback){
console.log(arg1);
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
console.log(result);
// result now equals 'done'
});



auto(tasks, [callback]) (多个函数有依赖关系,有的并行执行,有的依次执行)

用来处理有依赖关系的多个任务的执行。比如某些任务之间彼此独立,可以并行执行;但某些任务依赖于其它某些任务,只能等那些任务完成后才能执行。

虽然我们可以使用async.parallel和async.series结合起来实现该功能,但如果任务之间关系复杂,则代码会相当复杂,以后如果想添加一个新任务,也会很麻烦。这时使用async.auto,则会事半功倍。

如果有任务中途出错,则会把该错误传给最终callback,所有任务(包括已经执行完的)产生的数据将被忽略。

这里假设我要写一个程序,它要完成以下几件事:

从某处取得数据

在硬盘上建立一个新的目录

将数据写入到目录下某文件

发送邮件,将文件以附件形式发送给其它人。

分析该任务,可以知道1与2可以并行执行,3需要等1和2完成,4要等3完成。
async.auto({
getData: function(callback) {
setTimeout(function() {
console.log(’1 : got data’);
callback();
},
300);
},
makeFolder: function(callback) {
setTimeout(function() {
console.log(’1 : made folder’);
callback();
},
200);
},
writeFile: ['getData', 'makeFolder',
function(callback) {
setTimeout(function() {
console.log('1: wrote file');
callback(null, 'myfile');
},
300);
}],
emailFiles: ['writeFile',
function(callback, results) {
log('1: emailed file: ', results.writeFile); // -> myfile
callback(null, results.writeFile);
}]
},
function(err, results) {
log(’1 : err: ‘, err); // -> null
log(’1 : results: ‘, results); // -> { makeFolder: undefined,
// getData: undefined,
// writeFile: ‘myfile’,
// emailFiles: ‘myfile’ }
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: