summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Early <alexander.early@gmail.com>2015-05-28 00:19:24 -0700
committerAlexander Early <alexander.early@gmail.com>2015-05-28 00:19:24 -0700
commit13e1d81fc059d8e491397d01c2852b1f23950398 (patch)
tree2aa1feb6c55276ca66aee5cb6641b031298d8983
parenta514e183d1610754989785c442f1fa6690891363 (diff)
downloadasync-13e1d81fc059d8e491397d01c2852b1f23950398.tar.gz
experimental map changes
-rw-r--r--lib/async.js53
-rwxr-xr-xtest/test-async.js54
2 files changed, 59 insertions, 48 deletions
diff --git a/lib/async.js b/lib/async.js
index 38f2a4c..e44f29c 100644
--- a/lib/async.js
+++ b/lib/async.js
@@ -328,19 +328,21 @@
var completed = 0;
var started = 0;
var running = 0;
+ var errored = false;
(function replenish () {
if (completed >= size) {
return callback();
}
- while (running < limit && started < size) {
+ while (running < limit && started < size && !errored) {
started += 1;
running += 1;
var key = keys[started - 1];
iterator(obj[key], key, function (err) {
if (err) {
callback(err);
+ errored = true;
callback = function () {};
}
else {
@@ -379,38 +381,43 @@
};
}
+ function doParallelOf(fn) {
+ return function (obj, iterator, callback) {
+ return fn(async.eachOf, obj, iterator, callback);
+ };
+ }
+ function doParallelLimitOf(limit, fn) {
+ return function (obj, iterator, callback) {
+ return fn(_eachOfLimit(limit), obj, iterator, callback);
+ };
+ }
+ function doSeriesOf(fn) {
+ return function (obj, iterator, callback) {
+ return fn(async.eachOfSeries, obj, iterator, callback);
+ };
+ }
function _asyncMap(eachfn, arr, iterator, callback) {
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- if (!callback) {
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err) {
- callback(err);
- });
- });
- } else {
- var results = [];
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err, v) {
- results[x.index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
+ callback = callback || noop;
+ var results = [];
+ eachfn(arr, function (value, index, callback) {
+ iterator(value, function (err, v) {
+ results[index] = v;
+ callback(err);
});
- }
+ }, function (err) {
+ callback(err, results);
+ });
}
- async.map = doParallel(_asyncMap);
- async.mapSeries = doSeries(_asyncMap);
+ async.map = doParallelOf(_asyncMap);
+ async.mapSeries = doSeriesOf(_asyncMap);
async.mapLimit = function (arr, limit, iterator, callback) {
return _mapLimit(limit)(arr, iterator, callback);
};
function _mapLimit(limit) {
- return doParallelLimit(limit, _asyncMap);
+ return doParallelLimitOf(limit, _asyncMap);
}
// reduce only has a series version, as doing reduce in parallel won't
diff --git a/test/test-async.js b/test/test-async.js
index eba90e9..b3b84fe 100755
--- a/test/test-async.js
+++ b/test/test-async.js
@@ -1617,7 +1617,9 @@ exports['forEachOfLimit with array'] = function(test){
});
};
-exports['map'] = function(test){
+exports['map'] = {
+
+'basic': function(test){
var call_order = [];
async.map([1,3,2], mapIterator.bind(this, call_order), function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
@@ -1625,9 +1627,9 @@ exports['map'] = function(test){
test.same(results, [2,6,4]);
test.done();
});
-};
+},
-exports['map original untouched'] = function(test){
+'map original untouched': function(test){
var a = [1,2,3];
async.map(a, function(x, callback){
callback(null, x*2);
@@ -1636,9 +1638,9 @@ exports['map original untouched'] = function(test){
test.same(a, [1,2,3]);
test.done();
});
-};
+},
-exports['map without main callback'] = function(test){
+'map without main callback': function(test){
var a = [1,2,3];
var r = [];
async.map(a, function(x, callback){
@@ -1649,9 +1651,9 @@ exports['map without main callback'] = function(test){
test.done();
}
});
-};
+},
-exports['map error'] = function(test){
+'map error': function(test){
test.expect(1);
async.map([1,2,3], function(x, callback){
callback('error');
@@ -1659,9 +1661,9 @@ exports['map error'] = function(test){
test.equals(err, 'error');
});
setTimeout(test.done, 50);
-};
+},
-exports['mapSeries'] = function(test){
+'mapSeries': function(test){
var call_order = [];
async.mapSeries([1,3,2], mapIterator.bind(this, call_order), function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
@@ -1669,9 +1671,9 @@ exports['mapSeries'] = function(test){
test.same(results, [2,6,4]);
test.done();
});
-};
+},
-exports['mapSeries error'] = function(test){
+'mapSeries error': function(test){
test.expect(1);
async.mapSeries([1,2,3], function(x, callback){
callback('error');
@@ -1679,10 +1681,10 @@ exports['mapSeries error'] = function(test){
test.equals(err, 'error');
});
setTimeout(test.done, 50);
-};
+},
-exports['mapLimit'] = function(test){
+'mapLimit': function(test){
var call_order = [];
async.mapLimit([2,4,3], 2, mapIterator.bind(this, call_order), function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
@@ -1690,9 +1692,9 @@ exports['mapLimit'] = function(test){
test.same(results, [4,8,6]);
test.done();
});
-};
+},
-exports['mapLimit empty array'] = function(test){
+'mapLimit empty array': function(test){
test.expect(1);
async.mapLimit([], 2, function(x, callback){
test.ok(false, 'iterator should not be called');
@@ -1701,27 +1703,27 @@ exports['mapLimit empty array'] = function(test){
test.ok(true, 'should call callback');
});
setTimeout(test.done, 25);
-};
+},
-exports['mapLimit limit exceeds size'] = function(test){
+'mapLimit limit exceeds size': function(test){
var call_order = [];
async.mapLimit([0,1,2,3,4,5,6,7,8,9], 20, mapIterator.bind(this, call_order), function(err, results){
test.same(call_order, [0,1,2,3,4,5,6,7,8,9]);
test.same(results, [0,2,4,6,8,10,12,14,16,18]);
test.done();
});
-};
+},
-exports['mapLimit limit equal size'] = function(test){
+'mapLimit limit equal size': function(test){
var call_order = [];
async.mapLimit([0,1,2,3,4,5,6,7,8,9], 10, mapIterator.bind(this, call_order), function(err, results){
test.same(call_order, [0,1,2,3,4,5,6,7,8,9]);
test.same(results, [0,2,4,6,8,10,12,14,16,18]);
test.done();
});
-};
+},
-exports['mapLimit zero limit'] = function(test){
+'mapLimit zero limit': function(test){
test.expect(2);
async.mapLimit([0,1,2,3,4,5], 0, function(x, callback){
test.ok(false, 'iterator should not be called');
@@ -1731,9 +1733,9 @@ exports['mapLimit zero limit'] = function(test){
test.ok(true, 'should call callback');
});
setTimeout(test.done, 25);
-};
+},
-exports['mapLimit error'] = function(test){
+'mapLimit error': function(test){
test.expect(2);
var arr = [0,1,2,3,4,5,6,7,8,9];
var call_order = [];
@@ -1748,9 +1750,9 @@ exports['mapLimit error'] = function(test){
test.equals(err, 'error');
});
setTimeout(test.done, 25);
-};
+},
-exports['mapLimit does not continue replenishing after error'] = function (test) {
+'mapLimit does not continue replenishing after error': function (test) {
var started = 0;
var arr = [0,1,2,3,4,5,6,7,8,9];
var delay = 10;
@@ -1771,6 +1773,8 @@ exports['mapLimit does not continue replenishing after error'] = function (test)
test.equal(started, 3);
test.done();
}, maxTime);
+}
+
};