node lesson5--async

https://github.com/alsotang/node-lessons/tree/master/lesson5

https://github.com/nswbmw/N-blog/wiki/%E7%95%AA%E5%A4%96%E7%AF%87%E4%B9%8B%E2%80%94%E2%80%94%E4%BD%BF%E7%94%A8-Async

http://www.cnblogs.com/zoho/archive/2013/05/10/3072261.html

 

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

 

1). 集合: Collections

  • each: 如果想对同一个集合中的所有元素都执行同一个异步操作。
  • map: 对集合中的每一个元素,执行某个异步操作,得到结果。所有的结果将汇总到最终的callback里。与each的区别是,each只关心操作不管最后的值,而map关心的最后产生的值。
  • filter: 使用异步操作对集合中的元素进行筛选, 需要注意的是,iterator的callback只有一个参数,只能接收true或false。
  • reject: reject跟filter正好相反,当测试为true时则抛弃
  • reduce: 可以让我们给定一个初始值,用它与集合中的每一个元素做运算,最后得到一个值。reduce从左向右来遍历元素,如果想从右向左,可使用reduceRight。
  • detect: 用于取得集合中满足条件的第一个元素。
  • sortBy: 对集合内的元素进行排序,依据每个元素进行某异步操作后产生的值,从小到大排序。
  • some: 当集合中是否有至少一个元素满足条件时,最终callback得到的值为true,否则为false.
  • every: 如果集合里每一个元素都满足条件,则传给最终回调的result为true,否则为false
  • concat: 将多个异步操作的结果合并为一个数组。

2). 流程控制: Control Flow

  • series: 串行执行,一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。
  • parallel: 并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。
  • whilst: 相当于while,但其中的异步调用将在完成后才会进行下一次循环。
  • doWhilst: 相当于do…while, doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。
  • until: until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。
  • doUntil: doUntil与doWhilst正好相反,当test为false时循环,与true时跳出。其它特性一致。
  • forever: 无论条件循环执行,如果不出错,callback永远不被执行。
  • waterfall: 按顺序依次执行一组函数。每个函数产生的值,都将传给下一个。
  • compose: 创建一个包括一组异步函数的函数集合,每个函数会消费上一次函数的返回值。把f(),g(),h()异步函数,组合成f(g(h()))的形式,通过callback得到返回值。
  • applyEach: 实现给一数组中每个函数传相同参数,通过callback返回。如果只传第一个参数,将返回一个函数对象,我可以传参调用。
  • queue: 是一个串行的消息队列,通过限制了worker数量,不再一次性全部执行。当worker数量不够用时,新加入的任务将会排队等候,直到有新的worker可用。
  • cargo: 一个串行的消息队列,类似于queue,通过限制了worker数量,不再一次性全部执行。不同之处在于,cargo每次会加载满额的任务做为任务单元,只有任务单元中全部执行完成后,才会加载新的任务单元。
  • auto: 用来处理有依赖关系的多个任务的执行。
  • iterator: 将一组函数包装成为一个iterator,初次调用此iterator时,会执行定义中的第一个函数并返回第二个函数以供调用。
  • apply: 可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。
  • nextTick: 与nodejs的nextTick一样,再最后调用函数。
  • times: 异步运行,times可以指定调用几次,并把结果合并到数组中返回
  • timesSeries: 与time类似,唯一不同的是同步执行

3). 工具类: Utils

  • memoize: 让某一个函数在内存中缓存它的计算结果。对于相同的参数,只计算一次,下次就直接拿到之前算好的结果。
  • unmemoize: 让已经被缓存的函数,返回不缓存的函数引用。
  • log: 执行某异步函数,并记录它的返回值,日志输出。
  • dir: 与log类似,不同之处在于,会调用浏览器的console.dir()函数,显示为DOM视图。
  • noConflict: 如果之前已经在全局域中定义了async变量,当导入本async.js时,会先把之前的async变量保存起来,然后覆盖它。仅仅用于浏览器端,在nodejs中没用,这里无法演示。

http://blog.csdn.net/sxyizhiren/article/details/18240435

 

2.async.mapSeries

用法async.mapSeries(arr, iterator, callback)

arr是一个数组,不能是一个json对象。

作用的将arr中的每一项依次拿给iterator去执行,执行结果传给最后的callback

例子:

async.mapSeries([1,2,3,4], function(node,cb){cb(null,node+1);}, function(err,results){

console.log(results);

//这里打印[2,3,4,5],如果cb返回的结果有多个如cb(null,node+1,node+1,node+1,node+1),那么结果将是这种形式的:

//[[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5]]

});

同样如果iterator中调用cb()都是传的null,所有arr中的元素都能得到执行,如果某个iterator传递err给cb()。那么将直接跳到callback中去,传给callback的是(err,results).这里results自然是不完整的,所以没有意义。

 

 

3.async.mapLimit

用法:mapLimit(arr, limit, iterator, callback)

这个作用和mapSeries相似,唯一不同的是mapSeries是串行的,一个一个执行,而mapLimit可以同时执行limit个。

你可能会问,node单线程怎么能同时执行多个呢?当然这里的多个是指多个需要callback等待的异步操作。mapSeries是等待上一个callback回来再执行这一个;mapLimit是同时发起多个异步操作,然后一起等待callback的返回,返回一个就再发起下一个。

如果limit为1即mapLimit(arr, 1, iterator, callback),就和mapSeries(arr, iterator, callback)的作用一样了。

 

var express = require('express');//app
var async = require('async');
var app = express();
app.get('/', function(req, res, next){
    // 并发连接数的计数器
    var concurrencyCount = 0;
    var fetchUrl = function(url ,callback){
        // delay 的值在 2000 以内,是个随机的整数
        var delay = parseInt(Math.random() * 10000000 % 2000, 10);
        concurrencyCount++;
        console.log("现在的并发数是", concurrencyCount,',正在抓取的是', url,',耗时' + delay + '毫秒' );
        setTimeout(function(){
            concurrencyCount--;
            callback(null, url + ' html content');
        }, delay);
    };
    var urls = [];
    for(var i = 0; i < 30; i++){
        urls.push('http://datasource_' + i);
    };
    async.mapLimit(urls, 5, function(url, callback){
        fetchUrl(url, callback)
    }, function(err, result){
        console.log('final:');
        console.log(result);
    })
});

app.listen(8000, function(){
    console.log('this app is running at port 8000')
})

 

posted @ 2015-10-10 12:01  darr  阅读(213)  评论(0编辑  收藏  举报