当前位置: 首页 > 后端技术 > Node.js

从0到1学习节点(八)异步控制工具async

时间:2023-04-03 11:19:31 Node.js

系列索引:https://www.xiabingbao.com/node/2017/01/08/node-list.html本文地址:https:///www.xiabingbao.com/node/2017/02/25/node-async.html我们写异步程序的时候,最头疼的就是不知道什么时候会把结果返回给我们,然后再进行后续的操作.下面的操作放在返回成功的函数中,或者使用计数器等方法。典型的两种是:后面的操作需要依赖前面异步操作的结果;多个异步操作并行执行,所有执行完成后执行下一个操作。在这两个操作中,我们可以把第一个异步程序写成这样:db.select(SQL1,function(res1){db.delete(SQL2,function(res2){db.insert(SQL3,function(res3){//...})})});执行成功后将以下操作写入回调函数。对于第二个并行异步操作,可以使用counter方法。当每次异步调用成功时,计数器加1。当所有异步调用都成功后,再执行:varcount=0;varsuccess=function(){count++;if(count>=3){console.log('执行完成...');}}varselect=function(){db.select(sql,function(res){success();})}varselect2=function(){db.select(sql,function(res){success();})}varselect3=function(){db.select(sql,function(res){success();})}select();select2();select3();这些写法很麻烦,而且代码逻辑混乱,调试起来很不方便。那么我们就需要用到async这个异步控制的利器了。1.简介async的作用是对进程进行控制,它提供了很多调用的方法。这些方法可以分为三类:集合、控制流和实用程序。下面我们就从这三类中选出几个方法来进行讲解。2.功能介绍async中可用的方法很多,我们只说明其中比较有代表性的几个,其他的可以访问官方文档:http://caolan.github.io/async/docs。HTML。2.1Collection类Collection类中的方法主要有some、'map'、'each'、'every'等,这些方法是对数组或组合进行相同操作后统一执行回调函数。我们以地图为例。Map对集合中的每个元素执行相同的异步操作以获取结果。所有结果将汇总到最终回调中。在使用方法中,map接收三个参数,分别是:参数名类型描述colliterateecallbackArray|处理。该方法接收两个参数(item、callback);item是集合中的每一项,callback是回调函数。callback需要有err(有时可能为null)和处理后的数据,callback(err,data)是最后的回调函数,在处理集合时调用,传递两个参数err和result,result为之前处理的所有结果的集合注:中间处理函数iteratee并发处理coll中的每一项,所以不保证iteratee按顺序完成。但是,如果coll是一个数组,那么最终的结果集结果会按照coll的顺序排列;如果coll是一个集合(Object)类型,results会是一个数组类型,results会大致按照coll的key的顺序排列(不同的可能是你的JavaScript引擎不同)。举个例子,用map获取几个文件的内容:varfiles=['./file/cnode_1.txt','./file/cnode_2.txt','./file/cnode_3.txt'];//读取文件内容//第一个参数是文件名列表数组//第二个参数传递给数组中的每一项和回调函数//第三个参数results是所有结果的集合async.map(files,function(file,cb){fs.readFile(file,'utf-8',function(err,data){cb(err,data);})},function(err,results){console.log(results);})而且,如果中间的处理函数比较大,不想写在map里面,也可以写成一个单独的函数传入,但是传参还是需要遵守规则:varfiles=['./file/cnode_1.txt','./file/cnode_2.txt','./file/cnode_3.txt'];varread=function(file,cb){fs.readFile(file,'utf-8',function(err,data){cb(err,data);})}async.map(files,read,function(err,result){console.log(result);})这里还有一个mapLimit,可以传一个参数limit,用来限制并发数:mapLimit(coll,limit,iteratee,callbackopt)://并发数为2async.mapLimit(files,2,read,function(err,result){console.log(result);})同时collection类中还有其他方法,我们也稍微了解一下:each:类似于map,但是最终回调函数没有结果,each只循环,不负责处理结果every:中间处理函数iteratee(err,boolean)的参数需要传一个bOoolean值,如果所有options的结果都为true,则结果为truesome:类似于every,只是只要有一个options为true,结果就为truefilter:filtercoll,过滤掉符合reject:与filter正好相反,过滤掉false的结果concat:将每次异步操作的结果合并到一个数组中2.2流程控制类上面的集合类就是对一个集合进行同样的处理,其中的每一项集合处理完后,当回调结果,执行多个回调方法时,需要对这些回调方法进行控制。多个回调方法执行时,通常有几个过程:串行和无关,即一个执行完后,下一个依次执行,它们之间没有数据交互。全部执行完后,执行最后一个回调函数。可以使用async.series串行关联,即执行完一个,依次执行下一个,上一个回调函数的结果会作为下一个回调函数的参数。您可以并行使用async.waterfall。这些回调函数是同时并发执行的。都执行完之后,执行最后的回调函数。可以使用async.parallel,当然还有其他更复杂的过程,这里只说上面三种情况。async.series、async.waterfall和async.parallel的语法是一样的:async.Method(coll,function(err,results){})其中coll可以是数组也可以是json格式,results类型对应科尔。Serialandunassociatedasync.series://Serialandunassociated,数组格式async.series([function(cb){getAllList(function(result){cb(null,result);});},function(cb){getAllUser(function(result){cb(null,result);});}],function(err,result){console.log(result);})和串行异步可以是json格式://串行和不相关,jsonasync.series({one:function(cb){getAllList(function(result){cb(null,result);});},二:function(cb){getAllUser(function(result){cb(null,result);});}},function(err,result){console.log(result);})serialandassociatedasync.waterfall://serialandupAresult作为下一个异步的参数。waterfall([function(cb){getListById(1,function(result){cb(null,result);});},function(params,cb){console.log(params);getAllUser(function(result){cb(null,result);});}],function(err,result){console.log(result);})并行async.parallel://并行,getAllList和getAllUser同时执行async.parallel([function(cb){getAllList(function(result){cb(null,result);});},function(cb){getAllUser(function(result){cb(null,result);});}],function(err,result){console.log(result);})关于并行异步操作,还有一个async.parallelLimit,限制了numberofconcurrency://并发数为2async.parallelLimit([iteratee1,iteratee2,iteratee3,...],2,function(err,results){})2.3工具类async也提供了很多工具方法供使用,比如async.log可以在回调方法中输出值,第一个参数是函数,后面的参数是传递给函数的参数:varhello=function(name,callback){setTimeout(function(){callback(null,'hello'+name);},1000);};//将'world'传递给hello方法async.log(hello,'world');//'helloworld'还有apply,dir,timeout等方法3.总结用async控制异步过程很方便,前端也可以用,比如可以操作多个ajax请求等系列索引:https://www.xiabingbao.com/node/2017/01/08/node-list.html本文地址:https://www.xiabingbao.com/node/2017/02/25/node-async.html欢迎大家关注我的微信公众号: