Skip to content

Commit

Permalink
use iterator in eachSeries/Parallel functions to avoid creating an ex…
Browse files Browse the repository at this point in the history
…tra array
  • Loading branch information
Alexander Early committed Jun 1, 2015
1 parent c3d4c13 commit bf71c8c
Showing 1 changed file with 45 additions and 39 deletions.
84 changes: 45 additions & 39 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,24 @@
return keys;
};

function _iteratorKeys(coll) {
return _isArrayLike(coll) ?
// just plain _keys wont work with sparse arrays
_map(coll, function (_, index) { return index; }) :
_keys(coll);
function _keyIterator(coll) {
var i = -1;
var len;
var keys;
if (_isArrayLike(coll)) {
len = coll.length;
return function next() {
i++;
return i < len ? i : null;
};
} else {
keys = _keys(coll);
len = keys.length;
return function next() {
i++;
return i < len ? keys[i] : null;
};
}
}

function _baseSlice(arr, start) {
Expand Down Expand Up @@ -219,32 +232,24 @@
async.forEachOfSeries =
async.eachOfSeries = function (obj, iterator, callback) {
callback = callback || noop;
var keys = _iteratorKeys(obj);
var size = keys.length;
if (!size) {
return callback();
}
var completed = 0;
var nextKey = _keyIterator(obj);
function iterate() {
var sync = true;
var key = keys[completed];
var key = nextKey();
if (key === null) {
return callback(null);
}
iterator(obj[key], key, function (err) {
if (err) {
callback(err);
callback = noop;
}
else {
completed += 1;
if (completed >= size) {
callback(null);
if (sync) {
async.nextTick(iterate);
}
else {
if (sync) {
async.nextTick(iterate);
}
else {
iterate();
}
iterate();
}
}
});
Expand All @@ -264,40 +269,41 @@

return function (obj, iterator, callback) {
callback = callback || noop;
var keys = _iteratorKeys(obj);
var size = keys.length;
if (!size || limit <= 0) {
var nextKey = _keyIterator(obj);
if (limit <= 0) {
return callback(null);
}
var completed = 0;
var started = 0;
var done = false;
var running = 0;
var errored = false;

(function replenish () {
if (completed >= size) {
return callback();
if (done && running <= 0) {
callback(null);
callback = noop;
return;
}

while (running < limit && started < size && !errored) {
started += 1;
while (running < limit && !errored) {
var key = nextKey();
if (key === null) {
done = true;
if (running <= 0) {
callback(null);
callback = noop;
}
return;
}
running += 1;
var key = keys[started - 1];
iterator(obj[key], key, function (err) {
running -= 1;
if (err) {
callback(err);
errored = true;
callback = noop;
}
else {
completed += 1;
running -= 1;
if (completed >= size) {
callback(null);
}
else {
replenish();
}
replenish();
}
});
}
Expand Down

0 comments on commit bf71c8c

Please sign in to comment.