Skip to content

Commit bf71c8c

Browse files
author
Alexander Early
committed
use iterator in eachSeries/Parallel functions to avoid creating an extra array
1 parent c3d4c13 commit bf71c8c

File tree

1 file changed

+45
-39
lines changed

1 file changed

+45
-39
lines changed

lib/async.js

+45-39
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,24 @@
107107
return keys;
108108
};
109109

110-
function _iteratorKeys(coll) {
111-
return _isArrayLike(coll) ?
112-
// just plain _keys wont work with sparse arrays
113-
_map(coll, function (_, index) { return index; }) :
114-
_keys(coll);
110+
function _keyIterator(coll) {
111+
var i = -1;
112+
var len;
113+
var keys;
114+
if (_isArrayLike(coll)) {
115+
len = coll.length;
116+
return function next() {
117+
i++;
118+
return i < len ? i : null;
119+
};
120+
} else {
121+
keys = _keys(coll);
122+
len = keys.length;
123+
return function next() {
124+
i++;
125+
return i < len ? keys[i] : null;
126+
};
127+
}
115128
}
116129

117130
function _baseSlice(arr, start) {
@@ -219,32 +232,24 @@
219232
async.forEachOfSeries =
220233
async.eachOfSeries = function (obj, iterator, callback) {
221234
callback = callback || noop;
222-
var keys = _iteratorKeys(obj);
223-
var size = keys.length;
224-
if (!size) {
225-
return callback();
226-
}
227-
var completed = 0;
235+
var nextKey = _keyIterator(obj);
228236
function iterate() {
229237
var sync = true;
230-
var key = keys[completed];
238+
var key = nextKey();
239+
if (key === null) {
240+
return callback(null);
241+
}
231242
iterator(obj[key], key, function (err) {
232243
if (err) {
233244
callback(err);
234245
callback = noop;
235246
}
236247
else {
237-
completed += 1;
238-
if (completed >= size) {
239-
callback(null);
248+
if (sync) {
249+
async.nextTick(iterate);
240250
}
241251
else {
242-
if (sync) {
243-
async.nextTick(iterate);
244-
}
245-
else {
246-
iterate();
247-
}
252+
iterate();
248253
}
249254
}
250255
});
@@ -264,40 +269,41 @@
264269

265270
return function (obj, iterator, callback) {
266271
callback = callback || noop;
267-
var keys = _iteratorKeys(obj);
268-
var size = keys.length;
269-
if (!size || limit <= 0) {
272+
var nextKey = _keyIterator(obj);
273+
if (limit <= 0) {
270274
return callback(null);
271275
}
272-
var completed = 0;
273-
var started = 0;
276+
var done = false;
274277
var running = 0;
275278
var errored = false;
276279

277280
(function replenish () {
278-
if (completed >= size) {
279-
return callback();
281+
if (done && running <= 0) {
282+
callback(null);
283+
callback = noop;
284+
return;
280285
}
281286

282-
while (running < limit && started < size && !errored) {
283-
started += 1;
287+
while (running < limit && !errored) {
288+
var key = nextKey();
289+
if (key === null) {
290+
done = true;
291+
if (running <= 0) {
292+
callback(null);
293+
callback = noop;
294+
}
295+
return;
296+
}
284297
running += 1;
285-
var key = keys[started - 1];
286298
iterator(obj[key], key, function (err) {
299+
running -= 1;
287300
if (err) {
288301
callback(err);
289302
errored = true;
290303
callback = noop;
291304
}
292305
else {
293-
completed += 1;
294-
running -= 1;
295-
if (completed >= size) {
296-
callback(null);
297-
}
298-
else {
299-
replenish();
300-
}
306+
replenish();
301307
}
302308
});
303309
}

0 commit comments

Comments
 (0)