node.js 异步处理async

Async 异步流程控制

Async是node.js流程控制工具包,提供了直接而强大的异步功能。基于JavascriptNode.js设计,同时也可以直接在浏览器中使用。

Async提供了大约20个函数,包括常用的 map, reduce, filter, forEach 等,异步流程控制模式包括,串行(series),并行(parallel),瀑布(waterfall)等。

async主要实现了三个部分的流程控制功能:

1. 集合: Collections

2. 流程控制: Control Flow

3. 工具类: Utils

下载安装

下载地址:https://github.com/caolan/async/blob/master/lib/async.js

 

可使用npm命令安装:

 npm install async

 

在浏览器中安装:

bower install async

 

在浏览器中使用(支持IE6, IE7, IE8, FF3.6 and Chrome 5):

<script type="text/javascript" src="async.js"></script>
<script type="text/javascript">
 
    async.map(data, asyncProcess, function(err, results){
        alert(results);
    });
 
</script>

 

 

 

集合

 

each

async.each [1,2,3],  (item, done)->
console.log item
done
, (err)->
    console.log err

 

async.each [1,2,3], (item, callback)->
if item > 2
    console.log item
    callback
else
    console.log item
    callback 
, (err)->
    console.log err

 

obj = { dev:  “myDev”, test:  “myTest”}
configs = {}
async.forEachOf obj, (value, key, callback)->
     console.log key
     console.log value
     Callback
, (err)->
    Console.log err if err

each不同的是,forEachOf 迭代的参数是一个对象,对象的key做为迭代器的第二个参数。

map

async.map [1,2,3], (item,  callback)->
    //对数组中的每一项item, 进行处理
    callback null, item + 1   //返回
, (err, results)->
   //得到结果集results
   console.log results // 2,3,4

mapeach的区别是,map关心结果,返回结果集resultseach 不关心结果,不返回结果集。

 

filter

async.filter [1,2,3], (item, callback)->
callback item > 2  //按条件过滤数组,callback参数只能为truefalse
,(results)->
console.log(results)  //3

 

 

reject

async.reject[1,2,3], (item, callback)->
callback item > 2  // rejectfilter正好相反,当测试为true时则抛弃
,(results)->
console.log(results)  //1,2

 

 

reduce

可以让我们给定一个初始值,用它与集合中的每一个元素做运算,最后得到一个值。reduce从左向右来遍历元素,如果想从右向左,可使用reduceRight

async.reduce [123], 1, (meno, item, callback)->
callback meno+item //初始值1与数组中的每一项之和
, (err, result)->
console.log result // 7

 

 

detect

用于取得集合中满足条件的第一个元素。它分为并行与顺序执行两种方式,分别对应函数detectdetectSeries

async.detect [1,2,3], (item, callback)->
callback item > 1
, (result)->
console.log result  //2, 找到第一个大于1的数

 

sortBy

对集合内的元素进行排序,依据每个元素进行某异步操作后产生的值,从小到大排序。

async.sortBy [1,9,3,5], (item, callback)->
callback null, item    //从小到大排序
, (err, result) ->
console.log result

 

async.sortBy [1,9,3,5], (item, callback)->
callback null, item*-1    //从大到小排序
, (err, result) ->
console.log result

 

async.sortBy objs, (obj, callback)->
  callback null, obj.update//按对象的update字段(修改时间)从小到大排序
, (err, result) ->
  console.log result

 

some

当集合中是否有至少一个元素满足条件时,最终callback得到的值为true,否则为false

async.some [1,2,3],  (item, callback)->
callback item > 2
, (err, result)->
    console.log result //true

 

every

如果集合里每一个元素都满足条件,则传给最终回调的resulttrue,否则为false

async.every [1,2,3], (item, callback)->
callback item > 2
, (err, result)->
console.log result  // false

 

concat

将多个异步操作的结果合并为一个数组

data = {
  aaa: [11,22,33],
  bbb: [44,55],
  ccc: 66
}
keys = [
  {name: 'aaa'},
  {name: 'bbb'},
  {name: 'ccc'}
]
async.concat keys, (key, callback)->
  callback null , data[key.name]
, (err, result)->
  console.log JSON.stringify result  //[11,22,33,44,55,66]

 

 

流控制Control Flow

 

series

串行执行,一个函数数组中,每一个函数执行完成之后才能执行下一个函数。

async.series [
  (callback)->
    callback null, "function1"
  (callback)->
    callback null, "function2"
], (err, result)->
    console.log JSON.stringify result //["function1","function2"]

 

async.series [
  one:(callback)->
          callback null, "function1"
  two:(callback)->
          callback null, "function2"
], (err, result)->
    console.log JSON.stringify result //{one:"function1", two:"function2"}

 

parallel

并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。

async.parallel [
(callback)->
    callback null, “one”
(callback)->
    callback null, “two”
], (err, results)->
console.log results // [“one”,”two”]

 

async.parallel [
one:(callback)->
    callback null, 1
two:(callback)->
    callback null, 2
], (err, results)->
    console.log results // {one:1, two:2}
 

 

auto

执行多个函数,根据实际情况选择是串行执行还是并行执行

//前两个函数并行执行,后两个函数串行执行
async.auto {
    //获取数据data
get_data: (callback)->
    console.log “in get_data”
    callback null, data, “converted to array”
      //创建目录
make_folder: (callback)->
    console.log “in make_folder”
    callback null, “folder”                 
     //get_data,make_folder并行执行,执行完成后将获取的数据写入文件并保存在创建的目录中
write_file: [“get_data”, “make_folder”, (callback, results)->
    console.log (“in write_file”, JSON.stringify results)
    callback null, “filename”
],
     //write_file执行完成后,发送邮件
email_link: [“write_file”, (callback, results)->
    console.log “in email_link”, JSON.stringify(results)
    callback null,{file: results.write_file, email:”xx@xx.com"}
]
}, (err, results)->
    console.log results

 

waterfall

按顺序依次执行一组函数。每个函数产生的值,都将传给下一个。

async.waterfall [
  (callback)->
    callback null, "one", "two"
  (arg1, arg2, callback)->
    console.log "====#{arg1}====#{arg2}"  //====one====two
    callback null, "three"
  (arg1, callback)->
    console.log "===="+arg1        //====three
    callback null, "done"
], (err, result)->
  console.log result     //done

 

compose

创建一个包括一组异步函数的函数集合,每个函数会消费上一次函数的返回值。

add1 = (n, callback) ->
  callback null, n+1
mul3 = (n, callback)->
  callback null, n*3
add1-mul3 = async.compose(mul3, add1)  //从右到左调用函数
add1-mul3 4, (err, result)->
  console.log result  //15

 

whilst

 相当于while,但其中的异步调用将在完成后才会进行下一次循环。

count = 0
async.whilst(
     //条件
    ->
        return count < 5   //true,则第二个函数会继续执行,否则,调出循环 
//循环的主体
    (callback)->
        console.log "=========count:#{count}"
        count++
        callback()
//如果条件不满足,或者发生异常
    (err)->
        console.log err if err
)

 

dowhilst

相当于do…while, doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。

count = 0
async.whilst(
//循环的主体
   (callback)->
        console.log "=========count:#{count}"
        count++
        callback()
    //条件
    ->
        return count < 5   //true,则第二个函数会继续执行,否则,调出循环 
//如果条件不满足,或者发生异常
    (err)->
        console.log err if err
)

 

 

until

untilwhilst正好相反,当testfalse时循环,与true时跳出。其它特性一致。

 

 

doUntil

doUntildoWhilst正好相反,当testfalse时循环,与true时跳出。其它特性一致。

 

 

forever

无论条件循环执行,如果不出错,callback永远不被执行。

count = 0
async.forever(
    (next)->
        console.log "=========count:#{count++}"
        next()
    (err)->
        console.log err if err
)

 

retry

发生错误时,重复执行指定次数,执行成功则停止执行

myMethod = (callback)->
  console.log "============hello"
  callback "err"
//myMethod方法返回错误,所以会重复执行5次;如果callback没有错误,则只执行一次
async.retry(5, myMethod, (err, result)->
    console.log "err:"+err
    console.log "result:"+result
)

 

apply

apply是一个非常好用的函数,可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。

function(callback) { t.inc(3, callback); }
//等价于
async.apply(t.inc, 3);
 
async.parallel [
async.apply(t.inc, 3),
async.apply(t.fire, 100)
], (err, results)->
    console.log “JSON.stringify results”

 

 

 

nextTick

nodejsnextTick一样,再最后调用函数

call_order = []
async.nextTick( ()->
call_order.push(“two”)
)
call_order.push(“one”)
console.log call_order  //[“one”,”two”]

 

times

异步运行,可以指定调用几次,并把结果合并到数组中返回

async.times 5, (parm, next)->
    createUser parm, (err, user)->
        next err, user
, (err, users)->
    //得到5个user

 

memoize

让某一个函数在内存中缓存它的计算结果。对于相同的参数,只计算一次,下次就直接拿到之前算好的结果。

 

unmemoize

让已经被缓存的函数,返回不缓存的函数引用。

 

 

 

 

 

 

 

参考文献

https://www.npmjs.com/package/async

http://blog.fens.me/nodejs-async/

 

 

 

阅读更多
上一篇CPU过载内存溢出分析
下一篇Prometheus+Grafana监控平台搭建
想对作者说点什么? 我来说一句

async/await异步处理demo

2017年06月27日 10.69MB 下载

没有更多推荐了,返回首页

关闭
关闭