• async.js 学习教程(二)


    Collections

    详情请参考:http://freewind.me/blog/20120518/932.html

    collections模块主要实现对集合的遍历,排序,过滤,查询等功能

    1. forEach:对集合中每个元素进行异步操作
    2. map:对集合中的每个元素通过异步操作得到另一个值,得到新的集合
    3. filter:对集合中元素使用异步操作进行筛选,得到符合条件的集合
    4. reject:与filter相似,只是判断条件时正好相反,得到剩下的元素的集合
    5. reduce:使用一个初始值同集合中每一个元素进行异步操作,最后得到一个唯一的结果
    6. detect:得到集合中满足条件的第一个数据
    7. sortBy:对集合中的数据进行异步操作,再根据值从小到大排序
    8. some/any:集合中是否有至少一个元素满足条件
    9. every/all:集合中是否每个元素都满足条件
    10. concat:对集合中的元素进行异步操作,将结果集合并成一个数组

    1.each(arr, iterator, callback)  第一个参数为数组(array),第二个参数为iterator(item, callback),其中item为数组内元素,callback为回调,第三个参数为回调函数,用法为迭代数组内每一个元素,执行一个方法,完成时可以调用回调,当迭代器返回一个错误回调,可执行处理函数

    如果想对同一个集合中的所有元素都执行同一个异步操作,可以利用forEach函数。注意该函数将重点放在“执行过程”上,忽略运行后产生的数据。如果需要结果,可使用map函数。

    根据执行的方式不同,forEach提供了三个版本:

    1. 集合中所有元素并行执行
    2. 一个一个顺序执行
    3. 分批执行,同一批内并行,批与批之间按顺序
     1 // assuming openFiles is an array of file names 
     2 
     3 async.each(openFiles, function( file, callback) {
     4 
     5   // Perform operation on file here.
     6   console.log('Processing file ' + file);
     7 
     8   if( file.length > 32 ) {
     9     console.log('This file name is too long');
    10     callback('File name too long');
    11   } else {
    12     // Do work to process file here
    13     console.log('File processed');
    14     callback();
    15   }
    16 }, function(err){
    17     // if any of the file processing produced an error, err would equal that error
    18     if( err ) {
    19       // One of the iterations produced an error.
    20       // All processing will now stop.
    21       console.log('A file failed to process');
    22     } else {
    23       console.log('All files have been processed successfully');
    24     }
    25 });
     1 var arr = [{name:'Jack', delay: 200}, 
     2            {name:'Mike', delay: 100}, 
     3            {name:'Freewind', delay: 300}];
     4  
     5 async.forEach(arr, function(item, callback) { 
     6     log(’1.1 enter: ‘ + item.name); 
     7     setTimeout(function(){ 
     8         log(’1.1 handle: ‘ + item.name); 
     9         callback(); 
    10     }, item.delay); 
    11 }, function(err) { 
    12     log(’1.1 err: ‘ + err); 
    13 });

    它将打出如下结果:

    42.244> 1.1 enter: Jack 
    42.245> 1.1 enter: Mike 
    42.245> 1.1 enter: Freewind 
    42.350> 1.1 handle: Mike 
    42.445> 1.1 handle: Jack 
    42.554> 1.1 handle: Freewind 
    42.554> 1.1 err: undefined

    这个函数还有一个衍生函数

    eachLimit(arr, limit, iterator, callback)

    最前面的数据是当前的时间值(秒.毫秒),从中可以看到各异步操作是并行执行的。

    如果想同步执行,需要使用forEachSeries函数,它与forEach的用法一模一样,只是执行时是一个一个来的。这里就不给例子了。

    当集合中元素很多,既不想一次全部并行操作,又不想一个一个按顺序来,可以使用forEachLimit函数。它可以设定一批处理几个,每一批内并行执行,批与批之间顺序执行。

    1 async.forEachLimit(arr, 2, function(item, callback) { 
    2     log(’1.5 enter: ‘ + item.name); 
    3     setTimeout(function(){ 
    4         log(’1.5 handle: ‘ + item.name); 
    5         callback(null, item.name); 
    6     }, item.delay); 
    7 }, function(err) { 
    8     log(’1.5 err: ‘ + err); 
    9 });

    打印结果如下:

    42.247> 1.5 enter: Jack 
    42.248> 1.5 enter: Mike 
    42.351> 1.5 handle: Mike 
    42.352> 1.5 enter: Freewind 
    42.461> 1.5 handle: Jack 
    42.664> 1.5 handle: Freewind 
    42.664> 1.5 err: undefined

    详情请参考https://github.com/freewind/async_demo/blob/master/forEach.js

    2.map(arr, iterator, callback)  遍历集合产生新的结果集合

    map的重点是转换,即把集合中的元素通过异步操作转为另一个对象,最后可以得到转换后的对象数组。它也提供了并行与顺序执行两种方式。

    这里给一个示例,给集合中的每个元素以异步方式增加!:

     1 var arr = [{name:'Jack', delay:200}, {name:'Mike', delay: 100}, {name:'Freewind', delay:300}, {name:'Test', delay: 50}];
     2 async.map(arr, function(item, callback) { 
     3     log(’1.1 enter: ‘ + item.name); 
     4     setTimeout(function() { 
     5         log(’1.1 handle: ‘ + item.name); 
     6         callback(null, item.name+’!!!’); 
     7     }, item.delay); 
     8 }, function(err,results) { 
     9     log(’1.1 err: ‘, err); 
    10     log(’1.1 results: ‘, results); 
    11 });

    显示结果如下:

    54.569> 1.1 enter: Jack 
    54.569> 1.1 enter: Mike 
    54.569> 1.1 enter: Freewind 
    54.569> 1.1 enter: Test 
    54.629> 1.1 handle: Test 
    54.679> 1.1 handle: Mike 
    54.789> 1.1 handle: Jack 
    54.879> 1.1 handle: Freewind 
    54.879> 1.1 err: 
    54.879> 1.1 results: [ 'Jack!!!', 'Mike!!!', 'Freewind!!!', 'Test!!!' ]

    详情请参考:https://github.com/freewind/async_demo/blob/master/map.js

    3.filter(arr, iterator(item, callback(test)), callback(results))  

     reject(arr, iterator(item, callback(test)), callback(results))  数组过滤

    使用异步操作对集合中的元素进行筛选。需要注意的是,iterator的callback只有一个参数,只能接收true或false。

    对于出错,该函数没有做出任何处理,直接由nodejs抛出。所以需要注意对Error的处理。

    提供了并行与顺序执行两种方式。

    并行示例,找到所有>=3的元素:

    1 async.filter([1,2,3,4,5], function(item, callback) { 
    2     log(’1.1 enter: ‘ + item); 
    3     setTimeout(function() { 
    4         log(’1.1 test: ‘ + item); 
    5         callback(item>=3); 
    6     }, 200); 
    7 }, function(results) { 
    8     log(’1.1 results: ‘, results); 
    9 });

    打印结果如下:

    16.739> 1.1 enter: 1 
    16.749> 1.1 enter: 2 
    16.749> 1.1 enter: 3 
    16.749> 1.1 enter: 4 
    16.749> 1.1 enter: 5 
    16.749> 1.3 enter: 1 
    16.949> 1.1 test: 1 
    16.949> 1.1 test: 2 
    16.949> 1.1 test: 3 
    16.949> 1.1 test: 4 
    16.949> 1.1 test: 5 
    16.949> 1.1 results: [ 3, 4, 5 ]

    可见找到了满足条件的所有元素。

    如果需要顺序执行,可以使用filterSeries函数,它的用法与filter一样。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/filter_reject.js

    reject与filter相似,只是行为正好相反。当条件为true时,它将丢弃相应的元素。它也提供了并行与顺序执行两种方式。

    更多详细示例:https://github.com/freewind/async_demo/blob/master/filter_reject.js

     

  • 相关阅读:
    浅谈JavaScript中this指向的⼏种情况
    JavaScript、html简单的级联操作。
    异常处理中throws和throw的区别?
    java异常处理try-catch-finally的执行过程?
    什么是内连接、外连接、交叉连接(笛卡尔积)?
    主键和外键的区别
    集合和数组的比较(为什么要引入集合)?
    Java中对比单继承与多继承的优劣,以及java的解决方案
    数据库
    数据库集中控制的优势
  • 原文地址:https://www.cnblogs.com/fly-dog/p/3666764.html
Copyright © 2020-2023  润新知