summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCalvin French-Owen <calvin@segment.io>2012-11-20 17:44:49 -0800
committerCalvin French-Owen <calvin@segment.io>2012-11-20 17:44:49 -0800
commit49c7fd7d46e50444889dab174a785d87d2b70cd2 (patch)
tree1d32e75d2a55e3f7a41e025ef36463415359c9e0
parent96a7da519adc9e8cb3c187a2da4945f5edea71d3 (diff)
downloadasync-49c7fd7d46e50444889dab174a785d87d2b70cd2.tar.gz
Adding mapLimit
-rw-r--r--README.md29
-rw-r--r--lib/async.js67
2 files changed, 69 insertions, 27 deletions
diff --git a/README.md b/README.md
index 1430894..8c52fd5 100644
--- a/README.md
+++ b/README.md
@@ -226,6 +226,35 @@ processing. The results array will be in the same order as the original.
---------------------------------------
+<a name="mapLimit" />
+### mapLimit(arr, limit, iterator, callback)
+
+The same as map only the iterator is applied to batches of items in the
+array, in series. The next batch of iterators is only called once the current
+one has completed processing.
+
+__Arguments__
+
+* arr - An array to iterate over.
+* limit - How many items should be in each batch.
+* iterator(item, callback) - A function to apply to each item in the array.
+ The iterator is passed a callback which must be called once it has completed.
+ If no error has occured, the callback should be run without arguments or
+ with an explicit null argument.
+* callback(err, results) - A callback which is called after all the iterator
+ functions have finished, or an error has occurred. Results is an array of the
+ transformed items from the original array.
+
+__Example__
+
+```js
+async.map(['file1','file2','file3'], 1, fs.stat, function(err, results){
+ // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
<a name="filter" />
### filter(arr, iterator, callback)
diff --git a/lib/async.js b/lib/async.js
index bbbd05c..aeab289 100644
--- a/lib/async.js
+++ b/lib/async.js
@@ -118,40 +118,48 @@
};
async.forEachLimit = function (arr, limit, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length || limit <= 0) {
- return callback();
- }
- var completed = 0;
- var started = 0;
- var running = 0;
+ var fn = forEachLimit(limit);
+ fn.apply(null, [arr, iterator, callback]);
+ };
- (function replenish () {
- if (completed === arr.length) {
+ var forEachLimit = function (limit) {
+
+ return function (arr, iterator, callback) {
+ callback = callback || function () {};
+ if (!arr.length || limit <= 0) {
return callback();
}
+ var completed = 0;
+ var started = 0;
+ var running = 0;
- while (running < limit && started < arr.length) {
- started += 1;
- running += 1;
- iterator(arr[started - 1], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- running -= 1;
- if (completed === arr.length) {
- callback();
+ (function replenish () {
+ if (completed === arr.length) {
+ return callback();
+ }
+
+ while (running < limit && started < arr.length) {
+ started += 1;
+ running += 1;
+ iterator(arr[started - 1], function (err) {
+ if (err) {
+ callback(err);
+ callback = function () {};
}
else {
- replenish();
+ completed += 1;
+ running -= 1;
+ if (completed === arr.length) {
+ callback();
+ }
+ else {
+ replenish();
+ }
}
- }
- });
- }
- })();
+ });
+ }
+ })();
+ };
};
@@ -186,6 +194,11 @@
async.map = doParallel(_asyncMap);
async.mapSeries = doSeries(_asyncMap);
+ async.mapLimit = function (arr, limit, iterator, callback) {
+ var fn = forEachLimit(limit);
+ return _asyncMap.apply(null, [fn, arr, iterator, callback]);
+ };
+
// reduce only has a series version, as doing reduce in parallel won't
// work in many situations.