nodejs中Async库使用
2014-03-03 10:33
309 查看
“流程控制”本来是件比较简单的事,但是由于Nodejs的异步架构的实现方法,对于需要同步的业务逻辑,实现起来就比较麻烦。嵌套3-4层,代码就会变得的支离破碎了!
现在介绍一个库async ,链接是https://github.com/caolan/async
Async的内容分为三部分:
流程控制:简化十种常见流程的处理
集合处理:如何使用异步操作处理集合中的数据
工具类:几个常用的工具类
有多个异步函数需要依次调用,一个完成之后才能执行下一个。各函数之间没有数据的交换,仅仅需要保证其执行顺序。这时可使用series。
从中可以看到这嵌套还是比较多深的,如果再多几步,会更深。
在代码中忽略对了每一层err的处理,否则还都等加上 if(err) return callback(err),那就更麻烦了。
对于这种情况,使用async来处理,在每个step中执行一些操作,这时可写成:
返回结果:
step1
step2
['one', 'two']
依次执行一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。
如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且将会立刻会将该error以及已经执行了的函数的结果,传给series中最后那个callback。
当所有的函数执行完后(没有出错),则会把每个函数传给其回调函数的结果合并为一个数组,传给series最后的那个callback。
还可以json的形式来提供tasks。每一个属性都会被当作函数来执行,并且结果也会以json形式传给series最后的那个callback。这种方式可读性更高一些。
并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。
如果某个函数出错,则立刻将err和已经执行完的函数的结果值传给parallel最终的callback。其它未执行完的函数的值不会传到最终数据,但要占个位置。
同时支持json形式的tasks,其最终callback的结果也为json形式。
示例代码:
step2
step1
['one', 'two']
与seires相似,按顺序依次执行多个函数。不同之处,每一个函数产生的值,都将传给下一个函数。如果中途出错,后面的函数将不会被执行。错误信息以及之前产生的结果,将传给waterfall最终的callback。
这个函数名为(瀑布),可以想像瀑布从上到下,中途冲过一层层突起的石头。
用来处理有依赖关系的多个任务的执行。比如某些任务之间彼此独立,可以并行执行;但某些任务依赖于其它某些任务,只能等那些任务完成后才能执行。
虽然我们可以使用async.parallel和async.series结合起来实现该功能,但如果任务之间关系复杂,则代码会相当复杂,以后如果想添加一个新任务,也会很麻烦。这时使用async.auto,则会事半功倍。
如果有任务中途出错,则会把该错误传给最终callback,所有任务(包括已经执行完的)产生的数据将被忽略。
这里假设我要写一个程序,它要完成以下几件事:
从某处取得数据
在硬盘上建立一个新的目录
将数据写入到目录下某文件
发送邮件,将文件以附件形式发送给其它人。
分析该任务,可以知道1与2可以并行执行,3需要等1和2完成,4要等3完成。
现在介绍一个库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’ } });
相关文章推荐
- Node.js 淘宝运用
- Node.js 学习笔记之一
- INSTALL NODE.JS ON WINDOWS
- node.js开发之WebStrom9之主题,字体,编码设置及使用
- node.js
- node.js 和v8的理解
- Node.js 模块 包
- NodeJS基础
- Hadoop配置datanode无法连接到master
- node.js入门
- Node.js 究竟是什么?
- Node.js 简单学习
- User equivalence unavailable on all nodes
- CareerCup Randomly return a node in a binary tree
- Nodejs AES加密
- net_kernel:monitor_nodes 订阅node连接\断开消息
- Nodejs初阶之express
- springnodejs
- Nodejs初阶之express
- HTML DOM 节点介绍(nodeName,nodeValue,nodeType)