犹豫nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦,async的流程控制就是为了简化这些操作var async = require(‘async‘); 1、series(多个函数一次执行,之间没有数据交换)series(tasks,[callback])顺序执行数组、集合内的函数,当前面一个函数执行完成就会立即执行下一个函数,如果函数触发了错误,可以在callback函数中验证,否则会一直执行完成tasks有多个异步函数需要依次调用,一个完成之后才能执行下一个,各函数之间没有数据的交换,仅仅需要保证其执行顺序,这时可以使用series。tasks传的是一个数组函数
const async=require(‘async‘);async.series([ function(callback){ console.log("one"); callback(null,"one"); }, function(callback){ console.log("two"); callback(null,"two"); }],function(err,results){ console.log("err======"+err); console.log("results======"+results); console.log("typeof results======"+typeof (results));}) 运行之后输出:
one
two
err======null
results======one,two
typeof results======object
我觉得这里很重要的是err是上面两个函数的错误信息,而results这个参数是一个数组对象,他们的值是上面数组函数每个callback里面的参数以上代码详解: 1、依次执行一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。 2、如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且将会立刻将该error以及已经执行了的函数的结果传给series中最后的那个callback 3、当所有的函数执行完后(没有出错),则会把每个函数传给其回调函数的结果合并为一个数组,传递给series最后的那个callback。 4、还可以json的形式来提供tasks。每个属性都会被当作函数来执行,并且结果也会以json形式传给series最后那个callback,这种方式可读性更高一些。 5、如果中间某个函数出错,series函数如何处理:中间有函数出错。出错之后的函数不会执行,错误及之前正常执行的函数结果将传给最终的callback。 6、如果某个函数传给回调的值是undefined,null,{},[]等,series如何处理:如果某个函数传的数据是undefined, null, {}, []等,它们会原样传给最终callback。 7、另外还需要注意的是:多个series调用之间是不分先后的,因为series本身也是异步调用。模拟series多个函数中一个出错会如何
const async=require(‘async‘);async.series([ function(callback){ console.log("one"); callback("error","one"); }, function(callback){ console.log("two"); callback(null,"two"); }],function(err,results){ console.log("err======"+err); console.log("results======"+results); console.log("typeof results======"+typeof (results));})运行后输出:
one
err======error
results======one
typeof results======object
传json形式tasks
代码:
const async=require("async"); async.series({ one:function(callback){ setTimeout(function(){ callback(null,1); },200) }, two:function(callback){ setTimeout(function(){ callback(null,2); }) }},function(err,results){ console.log("results0====="+results[‘one‘]); console.log("results1====="+results[‘two‘]);})运行后输出:
results0=====1
results1=====2
这是一个json格式的results
2、parallel
parallel(tasks,[callback])并行执行数组集合内的方法,不用等到前一个函数执行完再执行下一个函数,如果函数促发了错误,可以再callback函数中验证
并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。
如果某个函数出错,则立刻将err和已经执行完的函数的结果值传给parallel最终的callback。其它未执行完的函数的值不会传到最终数据,但要占个位置。
同时支持json形式的tasks,其最终callback的结果也为json形式。
const async=require(‘async‘); async.parallel([ function(callback){ setTimeout(function(){ callback(null,"one"); },200) }, function(callback){ setTimeout(function(){ callback(null,"two"); },100); }],function(err,results){ console.log("err====="+err); console.log("results====="+results);})运行后输出:
err=====null
results=====one,two
代码:
const async=require(‘async‘); async.parallel([ function(callback){ setTimeout(function(){ callback(null,"one"); },400) }, function(callback){ setTimeout(function(){ callback("err","two"); },200); }, function(callback){ setTimeout(function(){ callback(null,"three"); },100); } ], function(err,results){ console.log("err====="+err); console.log("results====="+results); })运行后输出:
err=====err
results=====,two,three
代码:
const async=require(‘async‘); async.parallel({ one:function(callback){ setTimeout(function(){ callback(null,"one"); },400) }, two:function(callback){ setTimeout(function(){ callback(null,"two"); },200); }, three:function(callback){ setTimeout(function(){ callback(null,"three"); },100); }}, function(err,results){ console.log("err====="+err); console.log("results====="+results[‘one‘]); console.log("results====="+results[‘two‘]); console.log("results====="+results[‘three‘]); })运行后输出:
err=====null
results=====one
results=====two
results=====three
3、waterfall
waterfall(tasks,callback),多个函数依次执行,且前一个的输出为吼一个的输入,
与series相似,按顺序依次执行多个函数,不同之处是,每个函数产生的值,都将传给下一个函数,如果中途出错,后面的函数将不会被执行。错误信息以及之前产生的结果,将传给waterfall最终的callback;该函数不支持json格式的tasks,
* 注意,所有的callback都必须形如callback(err, result),但err参数在前面各函数中无需声明,它被自动处理。
中途有函数出错,其err和产生的值将直接传给最终callback,后面的函数不再执行
代码:
const async=require(‘async‘);async.waterfall([ function(callback){ callback(null,‘one‘,‘two‘); },function(args,arg2,callback){ callback(null,‘three‘); },function(arg1,callback){ callback(null,‘done‘); }],function(err,results){ console.log("results====="+results);})运行后输出:results=====done代码:
const async=require(‘async‘);async.waterfall([ function(callback){ callback(null,‘one‘,‘two‘); },function(args,arg2,callback){ callback("err",‘three‘); },function(arg1,callback){ callback(null,‘done‘); }],function(err,results){ console.log("results====="+results);})运行后输出:
results=====three
4、whilst
whilst(test,fn,callback),可用于异步调用的while,第一个参数为验证条件,第二个参数为执行函数,第三个参数为验证失败后回调函数,一般在延迟动画用的比较多
相当于while,但其中的异步调用将在完成后才会惊醒下一次循环,
代码:
const async=require(‘async‘);var count=0;async.whilst( function(){ //验证成功继续,失败回调 return count<5; }, function(callback){ //1秒过去该函数回调执行完毕,接着循环,知道count=5的时候,第一个方法过不去了,报错,走到第三个方法 console.log("count"+count); count++; setTimeout(callback,1000); }, function(err){ console.log("err"+err); })代码运行后输出:
count0
count1
count2
count3
count4
errnull
该函数的功能比较简单,条件变量通常定义在外面,可供每个函数访问,在循环中,异步调用时产生的值实际上被丢弃了,因为最后那个callback只能传入错误信息。
另外,第二个函数fn需要能接受一个函数cb,这个cd最终必须被执行,用于表示出错或正常结束
中途出错。出错后立刻调用第三个函数。
代码:
const async=require(‘async‘);var count=0;async.whilst( function(){ //验证成功继续,失败回调 return count<5; }, function(callback){ //5秒过去后 console.log("count"+count); count++; if(count===1){ callback("err"); }else{ setTimeout(callback,1000); } }, function(err){ console.log("err"+err); })运行后输出:
count0
errerr
第二个函数即使产生值,也会被忽略。第三个函数只能得到err。