|
107 | 107 | return keys;
|
108 | 108 | };
|
109 | 109 |
|
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 | + } |
115 | 128 | }
|
116 | 129 |
|
117 | 130 | function _baseSlice(arr, start) {
|
|
219 | 232 | async.forEachOfSeries =
|
220 | 233 | async.eachOfSeries = function (obj, iterator, callback) {
|
221 | 234 | 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); |
228 | 236 | function iterate() {
|
229 | 237 | var sync = true;
|
230 |
| - var key = keys[completed]; |
| 238 | + var key = nextKey(); |
| 239 | + if (key === null) { |
| 240 | + return callback(null); |
| 241 | + } |
231 | 242 | iterator(obj[key], key, function (err) {
|
232 | 243 | if (err) {
|
233 | 244 | callback(err);
|
234 | 245 | callback = noop;
|
235 | 246 | }
|
236 | 247 | else {
|
237 |
| - completed += 1; |
238 |
| - if (completed >= size) { |
239 |
| - callback(null); |
| 248 | + if (sync) { |
| 249 | + async.nextTick(iterate); |
240 | 250 | }
|
241 | 251 | else {
|
242 |
| - if (sync) { |
243 |
| - async.nextTick(iterate); |
244 |
| - } |
245 |
| - else { |
246 |
| - iterate(); |
247 |
| - } |
| 252 | + iterate(); |
248 | 253 | }
|
249 | 254 | }
|
250 | 255 | });
|
|
264 | 269 |
|
265 | 270 | return function (obj, iterator, callback) {
|
266 | 271 | 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) { |
270 | 274 | return callback(null);
|
271 | 275 | }
|
272 |
| - var completed = 0; |
273 |
| - var started = 0; |
| 276 | + var done = false; |
274 | 277 | var running = 0;
|
275 | 278 | var errored = false;
|
276 | 279 |
|
277 | 280 | (function replenish () {
|
278 |
| - if (completed >= size) { |
279 |
| - return callback(); |
| 281 | + if (done && running <= 0) { |
| 282 | + callback(null); |
| 283 | + callback = noop; |
| 284 | + return; |
280 | 285 | }
|
281 | 286 |
|
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 | + } |
284 | 297 | running += 1;
|
285 |
| - var key = keys[started - 1]; |
286 | 298 | iterator(obj[key], key, function (err) {
|
| 299 | + running -= 1; |
287 | 300 | if (err) {
|
288 | 301 | callback(err);
|
289 | 302 | errored = true;
|
290 | 303 | callback = noop;
|
291 | 304 | }
|
292 | 305 | else {
|
293 |
| - completed += 1; |
294 |
| - running -= 1; |
295 |
| - if (completed >= size) { |
296 |
| - callback(null); |
297 |
| - } |
298 |
| - else { |
299 |
| - replenish(); |
300 |
| - } |
| 306 | + replenish(); |
301 | 307 | }
|
302 | 308 | });
|
303 | 309 | }
|
|
0 commit comments