在NodeJS中使用流程控制工具Async

本文介绍一款流程控制工具async,在编写接口或者编写测试用例的过程中总是会用到它。

由于nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦。Async的流程控制就是为了简化这些操作。

在node.js的开发和学习过程中,开始我们的目的只有一个就是实现功能,并不注重代码质量和可读性,也没有这个意识。像我之前在接口的实现过程中滥用中间件,以为结果出来了,把它response.send(result)出去就万事大吉了。

后来参考别人的代码,真心感到惭愧,然后才一步步学会注重代码的可读性。对比一下,之前的代码:

//根据course_id查询一条课程信息,及章节列表
router.get('/getOne',courseController.findOne,chapterController.findByCourseID,function(req,res){
    var result=util.response.getInfoOK;
    result.item = req.course;
    result.courseitemList = req.courseitemList;
    req.course = null;
    req.courseitemList = null;
    res.send(result);
});


这种写法看起来非常简洁,它的思路是这样的,在这个接口中,我需要调用多个controller中的方法,request、response会跟随请求依次流向这个方法,通过request把参数带过去,通过response把请求结果带过来。


现在的代码:

//申请详情
router.get('/myServiceHandleInfo', function (req, res, next) {

    async.auto({
        rs:function(cb){  //user-server关系
            serviceCtrl.getHandleRS(req.query, function (err, result) {
                cb(err,JSON.parse(result));
            });
        },
        service:function(cb){  //服务详情
            console.log("sid:",req.query.sid);
            serviceCtrl.getInfo({sid:req.query.sid}, function (err, result) {
                console.log("service result:",result);
                cb(err,JSON.parse(result));
            });
        },
        app:function(cb){  //应用详情
            appCtrl.showAppDetail(req.query.appid, function (err, result) {
                cb(err,JSON.parse(result));
            });
        },
        appUser:['app', function(results,cb) {  //应用创建者详情
            userCtrl.getInfo({uid:results.app.obj.did},function(err,result){
                cb(err,JSON.parse(result));
            })
        }]
    },function(err,results){
        if (err) throw err;
        res.send(results);
    });
});


 使用async之后,代码结构性和可读性都得到了改善,相信你一旦使用后,就再也不能没有它了。


对比:

1. response中参数的名称不能重复,而且response的负担特别重。async只在入口处将参数给这个方法,async请求结果是通过回调函数带过来的。

2. 方法之间是一个执行完了,才会执行下一个。而async有同步、异步、自动等多种方式。
 

================ ===========  开始使用Async   ====== ========================


Async的内容分为三部分:

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

 
安装工具

npm install async --save -d


1.async.waterfall实例(多个函数依次执行,且前一个的输出为后一个的输入)

这个函数名为waterfall(瀑布),可以想像瀑布从上到下,按顺序依次执行多个函数。不同之处,每一个函数产生的值,都将传给下一个函数。如果中途出错,后面的函数将不会被执行。错误信息以及之前产生的结果,将传给waterfall最终的callback。
注意,该函数不支持json格式的tasks。
应用场景:在创建课程的接口中,首先解析表单和上传头像,然后保存课程到数据库

 

async.waterfall([
    function(cb) {
     util.formParse(req,function(err,result){  //from解析
              cb(err,result);
          });  
    },
    function(user, cb) {
        courseCtrl.create(course,function(err,result){ //保存到数据库
            cb(err,result);
        })
    }
], function (err, result) {
    if(err) throw  err;
    var results = util.response.regOK;
    results.item = result;
    res.send(results);
});

 
2.async.parallel 实例(多个函数并行执行)

并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。
如果某个函数出错,则立刻将err和已经执行完的函数的结果值传给parallel最终的callback。其它未执行完的函数的值不会传到最终数据,但要占个位置。
支持json形式的tasks,其最终callback的结果也为json形式。
应用场景:在获取课程列表接口中,要获取课程列表,同时获取课程数目

async.parallel({
     count:function(cb){
         courseController.count( req.query ,cb);   //课程数目
     },
     list:function(cb){
         courseController.getList( req.query ,cb);   //课程列表
     }
 },function(err,results){
    res.send(results);
 });

 
请求结果:

{
count:2,
list:[
         {
            courseid:xxx,
            name:xxx
         },
         {
            courseid:xxx,
            name:xxx
         }
     ]
}


3.async.auto实例(多个函数有依赖关系,有的并行执行,有的依次执行)

用来处理有依赖关系的多个任务的执行。比如某些任务之间彼此独立,可以并行执行;但某些任务依赖于其它某些任务,只能等那些任务完成后才能执行。虽然我们可以使用async.parallel和async.series结合起来实现该功能,但如果任务之间关系复杂,则代码会相当复杂,以后如果想添加一个新任务,也会很麻烦。这时使用async.auto,则会事半功倍。
如果有任务中途出错,则会把该错误传给最终callback,所有任务(包括已经执行完的)产生的数据将被忽略。
应用场景:

根据uid(用户id)和course_id(课程id)获取用户信息和用户收藏的视频:
根据uid,在user表中获取用户信息;
根据course_id,在course表中获取课程信息,含teacher_id;
根据teacher_id,在user表中获取讲师信息(上一步执行完,才能执行);
最后,返回userInfo,courseInfo,tearcherInfo;

async.auto({
    userInfo:function(cb){
            userCtrl.getInfo({uid:req.query.uid}, function (err, result) {   //用户信息
            cb(err,result);
        });
    },
    couseInfo:function(cb){
        courseCtrl.getInfo(req.query.courseid, function (err, result) {  //课程信息
            cb(err,result);
        });
    },
    tearcherInfo:['couseInfo', function(results,cb) {
        userCtrl.getInfo({uid:results.couseInfo.teacherid},function(err,result){  //讲师信息
            cb(err,result);
        });
    }]
},function(err,results){
    if (err) throw err;
    res.send(results);
});

 
请求结果:

{
userInfo:{
    uid:xxx,
    name:xxx
    },
courseInfo:{
    courseid:xxx,
    name:xxx
    },
tearcherInfo:{
    uid:xxx,
    name:xxx
    }
}


GitHub代码参考地址:https://github.com/wuwanyu/async.node.test

转载于:https://www.cnblogs.com/wuwanyu/p/wuwanyu20160407.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是使用 Node.js 实现自动打 tag 的步骤: 1. 安装 `git` 命令行工具,并确保它能在命令行使用。 2. 在项目根目录下运行 `npm init` 初始化 npm 项目,并在 package.json 文件添加 "scripts" 字段。 3. 在项目根目录下运行 `npm install simple-git --save` 安装 simple-git 模块。 4. 在项目根目录下新建一个文件,例如 tag.js,并编写以下代码: ``` const git = require('simple-git/promise')(); async function main() { // 获取当前分支名称 const branch = await git.branch(); // 获取项目的最新 commit 信息 const commit = await git.log(['-1']); const commitHash = commit.latest.hash; const commitMessage = commit.latest.message; // 打 tag await git.addTag(`${branch}-${commitHash}`, commitMessage); // 提交 tag await git.push('origin', `${branch}-${commitHash}`); } main(); ``` 5. 运行 `node tag.js` 即可实现自动打 tag 的功能。 注意:在实际使用时,你可能需要根据自己的需要修改上述代码的一些参数和选项,以实现更多的功能。例如,你可能希望获取当前的版本号,并将它用作 tag 的名称。你也可能希望指定一个远程仓库来推送 tag。 ### 回答2: 使用Node.js实现自动打Tag的功能可以借助一些现有的Node.js库和工具。 首先,可以使用GitHub或GitLab等版本控制系统的API来获取仓库的信息和文件的变动记录。可以使用node-gitlab或github-api等库来调用相关API。 其次,可以使用自然语言处理(NLP)的库来对提交的信息进行分析和处理。可以使用Node.js的自然语言处理库,如Natural或NLP.js等。 然后,可以使用关键词提取算法来从提交信息提取关键词。可以使用库如node-rake或node-textrank等进行关键词提取。 将获取到的关键词与已有的标签进行比较,可以使用模糊匹配或相似度算法来判断关键词与标签的相似性。可以使用字符串相似度算法库如string-similarity或natural等。 最后,将匹配的标签应用到仓库。可以使用版本控制系统的API来自动添加、修改或删除标签。 整个流程可以通过Node.js编写成一个自动打Tag的脚本,定期运行或与版本控制系统集成,实现自动打Tag的功能。 需要注意的是,自动打Tag功能的实现还需要考虑到规则的定制化和配置的灵活性,以适应不同的项目和团队需求。同时,关键词提取和标签匹配的准确性也需要根据具体情况进行优化和调整。 ### 回答3: 使用Node.js实现自动打tag的功能可以通过以下步骤完成: 1. 首先,创建一个Node.js项目并安装相关依赖。使用npm初始化项目,并安装需要的库,比如axios用于发送HTTP请求。 2. 在项目创建一个脚本文件,用于实现自动打tag的逻辑。可以将这个脚本命名为autoTag.js。 3. 在脚本引入所需的模块,比如axios和fs模块。使用axios发送HTTP请求,fs模块用于读取和写入文件。 4. 根据需求,你可能需要从一个数据源获取需要打tag的数据。可以使用axios发送HTTP请求获取数据,并将数据保存为一个JSON文件。 5. 读取保存的JSON文件,并遍历其的每一项数据。 6. 对于每一项数据,根据一定的规则生成tag,并将tag添加到数据。 7. 将更新后的数据写入到一个新的JSON文件。 8. 按需求调整脚本逻辑,比如定时运行脚本,可以使用setInterval或者node-schedule库。 9. 测试脚本功能,确保自动打tag的逻辑按预期运行。 以上是一个基本的实现思路和步骤,具体的实现细节和业务逻辑可能因项目需求而有所不同。根据实际情况,可能还需要和其他系统进行交互、处理异常情况等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值