[Pkg-javascript-commits] [node-async] 23/480: ensure map and filter results stay in the same order when processing in parallel

Jonas Smedegaard js at moszumanska.debian.org
Fri May 2 08:58:08 UTC 2014


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository node-async.

commit a57d319468960d4e56ff10cc032212976b7cb849
Author: Caolan McMahon <caolan at caolanmcmahon.com>
Date:   Wed Jun 9 22:53:38 2010 +0100

    ensure map and filter results stay in the same order when processing in parallel
---
 README.md          | 17 +++++++----------
 lib/async.js       | 18 ++++++++++++++----
 test/test-async.js | 46 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index c1b7172..88803a5 100644
--- a/README.md
+++ b/README.md
@@ -99,9 +99,8 @@ error to this callback, the main callback for the map function is immediately
 called with the error.
 
 Note, that since this function applies the iterator to each item in parallel
-there is no guarantee that the iterator functions will complete in order. The
-results array can be in a different order to the source array. If you need the
-order to be the same, then use mapSeries instead.
+there is no guarantee that the iterator functions will complete in order, however
+the results array will be in the same order as the original array.
 
 __Arguments__
 
@@ -123,8 +122,7 @@ __Example__
 
 The same as map only the iterator is applied to each item in the array in
 series. The next iterator is only called once the current one has completed
-processing, meaning the results array will be in the same order as the
-original.
+processing. The results array will be in the same order as the original.
 
 
 ### filter(arr, iterator, callback)
@@ -133,7 +131,7 @@ Returns a new array of all the values which pass an async truth test.
 _The callback for each iterator call only accepts a single argument of true or
 false, it does not accept an error argument first!_ This is inline with the
 way node libraries work with truth tests like path.exists. This operation is
-performed in parallel, so the results array may be in a different order to the
+performed in parallel, but the results array will be in the same order as the
 original.
 
 __Arguments__
@@ -154,8 +152,7 @@ __Example__
 
 The same as filter only the iterator is applied to each item in the array in
 series. The next iterator is only called once the current one has completed
-processing, meaning the results array will be in the same order as the
-original.
+processing. The results array will be in the same order as the original.
 
 
 ### reduce(arr, memo, iterator, callback)
@@ -370,10 +367,10 @@ __Example__
         write_file: ['get_data', 'make_folder', function(callback){
             // once there is some data and the directory exists,
             // write the data to a file in the directory
-        },
+        }],
         email_link: ['write_file', function(callback){
             // once the file is written let's email a link to it...
-        }
+        }]
     });
 
 This is a fairly trivial example, but to do this using the basic parallel and
diff --git a/lib/async.js b/lib/async.js
index e32d7c8..7f216b1 100644
--- a/lib/async.js
+++ b/lib/async.js
@@ -52,9 +52,12 @@ var doSeries = function(fn){
 
 var _map = function(eachfn, arr, iterator, callback){
     var results = [];
+    for(var i=0; i<arr.length; i++){
+        arr[i] = {index: i, value: arr[i]};
+    }
     eachfn(arr, function(x, callback){
-        iterator(x, function(err, v){
-            results.push(v);
+        iterator(x.value, function(err, v){
+            results[x.index] = v;
             callback(err);
         });
     }, function(err){
@@ -81,13 +84,20 @@ exports.reduce = function(arr, memo, iterator, callback){
 
 var _filter = function(eachfn, arr, iterator, callback){
     var results = [];
+    for(var i=0; i<arr.length; i++){
+        arr[i] = {index: i, value: arr[i]};
+    }
     eachfn(arr, function(x, callback){
-        iterator(x, function(v){
+        iterator(x.value, function(v){
             if(v) results.push(x);
             callback();
         });
     }, function(err){
-        callback(results);
+        callback(results.sort(function(a,b){
+            return a.index - b.index;
+        }).map(function(x){
+            return x.value;
+        }));
     });
 };
 exports.filter = doParallel(_filter);
diff --git a/test/test-async.js b/test/test-async.js
index c7da60b..1191305 100644
--- a/test/test-async.js
+++ b/test/test-async.js
@@ -163,20 +163,31 @@ exports['waterfall multiple callback calls'] = function(test){
 
 
 exports['parallel'] = function(test){
+    var call_order = [];
     async.parallel([
         function(callback){
-            setTimeout(function(){callback(null, 1);}, 25);
+            setTimeout(function(){
+                call_order.push(1);
+                callback(null, 1);
+            }, 25);
         },
         function(callback){
-            setTimeout(function(){callback(null, 2);}, 50);
+            setTimeout(function(){
+                call_order.push(2);
+                callback(null, 2);
+            }, 50);
         },
         function(callback){
-            setTimeout(function(){callback(null, 3,3);}, 15);
+            setTimeout(function(){
+                call_order.push(3);
+                callback(null, 3,3);
+            }, 15);
         }
     ],
     function(err, results){
         test.equals(err, null);
-        test.same(results, [[3,3],1,2]);
+        test.same(call_order, [3,1,2]);
+        test.same(results, [1,2,[3,3]]);
         test.done();
     });
 };
@@ -204,20 +215,31 @@ exports['parallel no callback'] = function(test){
 };
 
 exports['series'] = function(test){
+    var call_order = [];
     async.series([
         function(callback){
-            setTimeout(function(){callback(null, 1);}, 25);
+            setTimeout(function(){
+                call_order.push(1);
+                callback(null, 1);
+            }, 25);
         },
         function(callback){
-            setTimeout(function(){callback(null, 2);}, 50);
+            setTimeout(function(){
+                call_order.push(2);
+                callback(null, 2);
+            }, 50);
         },
         function(callback){
-            setTimeout(function(){callback(null, 3,3);}, 15);
+            setTimeout(function(){
+                call_order.push(3);
+                callback(null, 3,3);
+            }, 15);
         }
     ],
     function(err, results){
         test.equals(err, null);
         test.same(results, [1,2,[3,3]]);
+        test.same(call_order, [1,2,3]);
         test.done();
     });
 };
@@ -345,12 +367,15 @@ exports['forEachSeries error'] = function(test){
 };
 
 exports['map'] = function(test){
+    var call_order = [];
     async.map([1,3,2], function(x, callback){
         setTimeout(function(){
+            call_order.push(x);
             callback(null, x*2);
         }, x*25);
     }, function(err, results){
-        test.same(results, [2,4,6]);
+        test.same(call_order, [1,2,3]);
+        test.same(results, [2,6,4]);
         test.done();
     });
 };
@@ -366,11 +391,14 @@ exports['map error'] = function(test){
 };
 
 exports['mapSeries'] = function(test){
+    var call_order = [];
     async.mapSeries([1,3,2], function(x, callback){
         setTimeout(function(){
+            call_order.push(x);
             callback(null, x*2);
         }, x*25);
     }, function(err, results){
+        test.same(call_order, [1,3,2]);
         test.same(results, [2,6,4]);
         test.done();
     });
@@ -418,7 +446,7 @@ exports['filter'] = function(test){
     async.filter([3,1,2], function(x, callback){
         setTimeout(function(){callback(x % 2);}, x*25);
     }, function(results){
-        test.same(results, [1,3]);
+        test.same(results, [3,1]);
         test.done();
     });
 };

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-async.git



More information about the Pkg-javascript-commits mailing list