nodejs中Async库使用

“流程控制”本来是件比较简单的事,但是由于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’ }
});



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值