async.js 學習教程(二)

Collections

詳情請參考:http://freewind.me/blog/20120518/932.htmlhtml

collections模塊主要實現對集合的遍歷,排序,過濾,查詢等功能node

 

  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爲回調,第三個參數爲回調函數,用法爲迭代數組內每個元素,執行一個方法,完成時能夠調用回調,當迭代器返回一個錯誤回調,可執行處理函數git

 

若是想對同一個集合中的全部元素都執行同一個異步操做,能夠利用forEach函數。注意該函數將重點放在「執行過程」上,忽略運行後產生的數據。若是須要結果,可以使用map函數。github

根據執行的方式不一樣,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

 

這個函數還有一個衍生函數async

eachLimit(arr, limit, iterator, callback)函數

最前面的數據是當前的時間值(秒.毫秒),從中能夠看到各異步操做是並行執行的。spa

若是想同步執行,須要使用forEachSeries函數,它與forEach的用法如出一轍,只是執行時是一個一個來的。這裏就不給例子了。code

當集合中元素不少,既不想一次所有並行操做,又不想一個一個按順序來,可使用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

相關文章
相關標籤/搜索