Async使用

标签: async node.js 流程控制
7人阅读 评论(0) 收藏 举报

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/

 

 

 

查看评论

async/await的使用以及注意事项

使用 async / await, 搭配 promise, 可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性. 本文介绍 async / await 的基本用法和一些注意事项.aw...
  • juhaotian
  • juhaotian
  • 2017-12-29 18:17:19
  • 3741

ES6 async/await在项目中的应用

最近在项目中有这么一个需求,当用户使用积分去兑换某个商品之后,点击某个按钮会调用两个接口,其中先调用一个接口,从接口中获取record_id之后,再调用另外一个接口,将获得的record_id传递到第...
  • u012863664
  • u012863664
  • 2017-10-23 17:20:10
  • 466

Node.js 使用async模块

假设要编写一些异步的代码: - 打开路径的句柄 - 判断路径是否指向一个文件 - 如果路径指向一个文件,加载这个文件的内容 - 关闭句柄并将内容返回给调用者 ...
  • github_36704158
  • github_36704158
  • 2017-04-14 17:22:17
  • 788

快速理解和使用 ES7 await/async

await/async 是 ES7 最重要特性之一,它是目前为止 JS 最佳的异步解决方案了。虽然没有在 ES2016 中录入,但很快就到来,目前已经在 ES-Next Stage 4 阶段。 ...
  • sinat_17775997
  • sinat_17775997
  • 2017-05-14 10:01:22
  • 1819

@Async @Scheduled 调度

spring 3中的@async初探 博客分类:  JAVA相关 spring    在spring 3中,@Async注解能让某个方法快速变为异步执行,马上来先DEMO上手下。  假如在网...
  • rainyear
  • rainyear
  • 2014-01-22 00:41:12
  • 2263

React/Redux应用使用Async/Await

Async/Await Async/Await是尚未正式公布的ES7标准新特性。简而言之,就是让你以同步方法的思维编写异步代码。对于前端,异步任务代码的编写经历了 callback 到现在流行的...
  • sinat_17775997
  • sinat_17775997
  • 2017-06-21 08:57:05
  • 3856

spring @Async的配置和使用

这个注解用于标注某个方法或某个类里面的所有方法都是需要异步处理的。被注解的方法被调用的时候,会在新线程中执行,而调用它的方法会在原来的线程中执行。这样可以避免阻塞、以及保证任务的实时性。适用于处理lo...
  • chendaoqiu
  • chendaoqiu
  • 2016-11-10 17:25:29
  • 1450

@Async的用法

@Async的用法
  • paraller_15
  • paraller_15
  • 2017-10-31 15:23:14
  • 104

Async and await的使用

遇到Async 和await总是不知所措,今天立志要把这个问题拿下。在网上参考了很多文章,结果有很多说使用await会产生新的线程,而有的文章则说不会产生线程,看的我头都大了。幸好谷歌到了微软的msd...
  • zhuoyue008
  • zhuoyue008
  • 2016-11-25 19:34:17
  • 521

vs2010之Async一瞥

首先,写一个函数来实现基本算法:   #region Do things         public long DoSomething(int n)         {           ...
  • cuoban
  • cuoban
  • 2015-12-31 13:41:41
  • 1158
    个人资料
    等级:
    访问量: 3122
    积分: 114
    排名: 122万+
    文章分类