UNPKG

229 kBJavaScriptView Raw
1(function (global, factory) {
2 /*jshint -W030 */
3 'use strict';
4 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5 typeof define === 'function' && define.amd ? define(['exports'], factory) :
6 global.async ? factory(global.neo_async = global.neo_async || {}) :
7 factory(global.async = global.async || {});
8}(this, function(exports) {
9
10 'use strict';
11
12 var noop = function noop() {};
13 var throwError = function throwError() {
14 throw new Error('Callback was already called.');
15 };
16
17 var DEFAULT_TIMES = 5;
18 var DEFAULT_INTERVAL = 0;
19
20 var obj = 'object';
21 var func = 'function';
22 var isArray = Array.isArray;
23 var nativeKeys = Object.keys;
24 var nativePush = Array.prototype.push;
25 var iteratorSymbol = typeof Symbol === func && Symbol.iterator;
26
27 var nextTick, asyncNextTick, asyncSetImmediate;
28 createImmediate();
29
30 /**
31 * @memberof async
32 * @namespace each
33 * @param {Array|Object} collection
34 * @param {Function} iterator
35 * @param {Function} callback
36 * @example
37 *
38 * // array
39 * var order = [];
40 * var array = [1, 3, 2];
41 * var iterator = function(num, done) {
42 * setTimeout(function() {
43 * order.push(num);
44 * done();
45 * }, num * 10);
46 * };
47 * async.each(array, iterator, function(err, res) {
48 * console.log(res); // undefined
49 * console.log(order); // [1, 2, 3]
50 * });
51 *
52 * @example
53 *
54 * // array with index
55 * var order = [];
56 * var array = [1, 3, 2];
57 * var iterator = function(num, index, done) {
58 * setTimeout(function() {
59 * order.push([num, index]);
60 * done();
61 * }, num * 10);
62 * };
63 * async.each(array, iterator, function(err, res) {
64 * console.log(res); // undefined
65 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
66 * });
67 *
68 * @example
69 *
70 * // object
71 * var order = [];
72 * var object = { a: 1, b: 3, c: 2 };
73 * var iterator = function(num, done) {
74 * setTimeout(function() {
75 * order.push(num);
76 * done();
77 * }, num * 10);
78 * };
79 * async.each(object, iterator, function(err, res) {
80 * console.log(res); // undefined
81 * console.log(order); // [1, 2, 3]
82 * });
83 *
84 * @example
85 *
86 * // object with key
87 * var order = [];
88 * var object = { a: 1, b: 3, c: 2 };
89 * var iterator = function(num, key, done) {
90 * setTimeout(function() {
91 * order.push([num, key]);
92 * done();
93 * }, num * 10);
94 * };
95 * async.each(object, iterator, function(err, res) {
96 * console.log(res); // undefined
97 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
98 * });
99 *
100 * @example
101 *
102 * // break
103 * var order = [];
104 * var array = [1, 3, 2];
105 * var iterator = function(num, done) {
106 * setTimeout(function() {
107 * order.push(num);
108 * done(null, num !== 2);
109 * }, num * 10);
110 * };
111 * async.each(array, iterator, function(err, res) {
112 * console.log(res); // undefined
113 * console.log(order); // [1, 2]
114 * });
115 *
116 */
117 var each = createEach(arrayEach, baseEach, symbolEach);
118
119 /**
120 * @memberof async
121 * @namespace map
122 * @param {Array|Object} collection
123 * @param {Function} iterator
124 * @param {Function} callback
125 * @example
126 *
127 * // array
128 * var order = [];
129 * var array = [1, 3, 2];
130 * var iterator = function(num, done) {
131 * setTimeout(function() {
132 * order.push(num);
133 * done(null, num);
134 * }, num * 10);
135 * };
136 * async.map(array, iterator, function(err, res) {
137 * console.log(res); // [1, 3, 2];
138 * console.log(order); // [1, 2, 3]
139 * });
140 *
141 * @example
142 *
143 * // array with index
144 * var order = [];
145 * var array = [1, 3, 2];
146 * var iterator = function(num, index, done) {
147 * setTimeout(function() {
148 * order.push([num, index]);
149 * done(null, num);
150 * }, num * 10);
151 * };
152 * async.map(array, iterator, function(err, res) {
153 * console.log(res); // [1, 3, 2]
154 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
155 * });
156 *
157 * @example
158 *
159 * // object
160 * var order = [];
161 * var object = { a: 1, b: 3, c: 2 };
162 * var iterator = function(num, done) {
163 * setTimeout(function() {
164 * order.push(num);
165 * done(null, num);
166 * }, num * 10);
167 * };
168 * async.map(object, iterator, function(err, res) {
169 * console.log(res); // [1, 3, 2]
170 * console.log(order); // [1, 2, 3]
171 * });
172 *
173 * @example
174 *
175 * // object with key
176 * var order = [];
177 * var object = { a: 1, b: 3, c: 2 };
178 * var iterator = function(num, key, done) {
179 * setTimeout(function() {
180 * order.push([num, key]);
181 * done(null, num);
182 * }, num * 10);
183 * };
184 * async.map(object, iterator, function(err, res) {
185 * console.log(res); // [1, 3, 2]
186 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
187 * });
188 *
189 */
190 var map = createMap(arrayEachIndex, baseEachIndex, symbolEachIndex, true);
191
192 /**
193 * @memberof async
194 * @namespace mapValues
195 * @param {Array|Object} collection
196 * @param {Function} iterator
197 * @param {Function} callback
198 * @example
199 *
200 * // array
201 * var order = [];
202 * var array = [1, 3, 2];
203 * var iterator = function(num, done) {
204 * setTimeout(function() {
205 * order.push(num);
206 * done(null, num);
207 * }, num * 10);
208 * };
209 * async.mapValues(array, iterator, function(err, res) {
210 * console.log(res); // { '0': 1, '1': 3, '2': 2 }
211 * console.log(order); // [1, 2, 3]
212 * });
213 *
214 * @example
215 *
216 * // array with index
217 * var order = [];
218 * var array = [1, 3, 2];
219 * var iterator = function(num, index, done) {
220 * setTimeout(function() {
221 * order.push([num, index]);
222 * done(null, num);
223 * }, num * 10);
224 * };
225 * async.mapValues(array, iterator, function(err, res) {
226 * console.log(res); // { '0': 1, '1': 3, '2': 2 }
227 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
228 * });
229 *
230 * @example
231 *
232 * // object
233 * var order = [];
234 * var object = { a: 1, b: 3, c: 2 };
235 * var iterator = function(num, done) {
236 * setTimeout(function() {
237 * order.push(num);
238 * done(null, num);
239 * }, num * 10);
240 * };
241 * async.mapValues(object, iterator, function(err, res) {
242 * console.log(res); // { a: 1, b: 3, c: 2 }
243 * console.log(order); // [1, 2, 3]
244 * });
245 *
246 * @example
247 *
248 * // object with key
249 * var order = [];
250 * var object = { a: 1, b: 3, c: 2 };
251 * var iterator = function(num, key, done) {
252 * setTimeout(function() {
253 * order.push([num, key]);
254 * done(null, num);
255 * }, num * 10);
256 * };
257 * async.mapValues(object, iterator, function(err, res) {
258 * console.log(res); // { a: 1, b: 3, c: 2 }
259 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
260 * });
261 *
262 */
263 var mapValues = createMap(arrayEachIndex, baseEachKey, symbolEachKey, false);
264
265 /**
266 * @memberof async
267 * @namespace filter
268 * @param {Array|Object} collection
269 * @param {Function} iterator
270 * @param {Function} callback
271 * @example
272 *
273 * // array
274 * var order = [];
275 * var array = [1, 3, 2];
276 * var iterator = function(num, done) {
277 * setTimeout(function() {
278 * order.push(num);
279 * done(null, num % 2);
280 * }, num * 10);
281 * };
282 * async.filter(array, iterator, function(err, res) {
283 * console.log(res); // [1, 3];
284 * console.log(order); // [1, 2, 3]
285 * });
286 *
287 * @example
288 *
289 * // array with index
290 * var order = [];
291 * var array = [1, 3, 2];
292 * var iterator = function(num, index, done) {
293 * setTimeout(function() {
294 * order.push([num, index]);
295 * done(null, num % 2);
296 * }, num * 10);
297 * };
298 * async.filter(array, iterator, function(err, res) {
299 * console.log(res); // [1, 3];
300 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
301 * });
302 *
303 * @example
304 *
305 * // object
306 * var order = [];
307 * var object = { a: 1, b: 3, c: 2 };
308 * var iterator = function(num, done) {
309 * setTimeout(function() {
310 * order.push(num);
311 * done(null, num % 2);
312 * }, num * 10);
313 * };
314 * async.filter(object, iterator, function(err, res) {
315 * console.log(res); // [1, 3];
316 * console.log(order); // [1, 2, 3]
317 * });
318 *
319 * @example
320 *
321 * // object with key
322 * var order = [];
323 * var object = { a: 1, b: 3, c: 2 };
324 * var iterator = function(num, key, done) {
325 * setTimeout(function() {
326 * order.push([num, key]);
327 * done(null, num % 2);
328 * }, num * 10);
329 * };
330 * async.filter(object, iterator, function(err, res) {
331 * console.log(res); // [1, 3];
332 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
333 * });
334 *
335 */
336 var filter = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, true);
337
338 /**
339 * @memberof async
340 * @namespace filterSeries
341 * @param {Array|Object} collection
342 * @param {Function} iterator
343 * @param {Function} callback
344 * @example
345 *
346 * // array
347 * var order = [];
348 * var array = [1, 3, 2];
349 * var iterator = function(num, done) {
350 * setTimeout(function() {
351 * order.push(num);
352 * done(null, num % 2);
353 * }, num * 10);
354 * };
355 * async.filterSeries(array, iterator, function(err, res) {
356 * console.log(res); // [1, 3];
357 * console.log(order); // [1, 3, 2]
358 * });
359 *
360 * @example
361 *
362 * // array with index
363 * var order = [];
364 * var array = [1, 3, 2];
365 * var iterator = function(num, index, done) {
366 * setTimeout(function() {
367 * order.push([num, index]);
368 * done(null, num % 2);
369 * }, num * 10);
370 * };
371 * async.filterSeries(array, iterator, function(err, res) {
372 * console.log(res); // [1, 3]
373 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
374 * });
375 *
376 * @example
377 *
378 * // object
379 * var order = [];
380 * var object = { a: 1, b: 3, c: 2 };
381 * var iterator = function(num, done) {
382 * setTimeout(function() {
383 * order.push(num);
384 * done(null, num % 2);
385 * }, num * 10);
386 * };
387 * async.filterSeries(object, iterator, function(err, res) {
388 * console.log(res); // [1, 3]
389 * console.log(order); // [1, 3, 2]
390 * });
391 *
392 * @example
393 *
394 * // object with key
395 * var order = [];
396 * var object = { a: 1, b: 3, c: 2 };
397 * var iterator = function(num, key, done) {
398 * setTimeout(function() {
399 * order.push([num, key]);
400 * done(null, num % 2);
401 * }, num * 10);
402 * };
403 * async.filterSeries(object, iterator, function(err, res) {
404 * console.log(res); // [1, 3]
405 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
406 * });
407 *
408 */
409 var filterSeries = createFilterSeries(true);
410
411 /**
412 * @memberof async
413 * @namespace filterLimit
414 * @param {Array|Object} collection
415 * @param {number} limit - limit >= 1
416 * @param {Function} iterator
417 * @param {Function} callback
418 * @example
419 *
420 * // array
421 * var order = [];
422 * var array = [1, 5, 3, 4, 2];
423 * var iterator = function(num, done) {
424 * setTimeout(function() {
425 * order.push(num);
426 * done(null, num % 2);
427 * }, num * 10);
428 * };
429 * async.filterLimit(array, 2, iterator, function(err, res) {
430 * console.log(res); // [1, 5, 3]
431 * console.log(order); // [1, 3, 5, 2, 4]
432 * });
433 *
434 * @example
435 *
436 * // array with index
437 * var order = [];
438 * var array = [1, 5, 3, 4, 2];
439 * var iterator = function(num, index, done) {
440 * setTimeout(function() {
441 * order.push([num, index]);
442 * done(null, num % 2);
443 * }, num * 10);
444 * };
445 * async.filterLimit(array, 2, iterator, function(err, res) {
446 * console.log(res); // [1, 5, 3]
447 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
448 * });
449 *
450 * @example
451 *
452 * // object
453 * var order = [];
454 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
455 * var iterator = function(num, done) {
456 * setTimeout(function() {
457 * order.push(num);
458 * done(null, num % 2);
459 * }, num * 10);
460 * };
461 * async.filterLimit(object, 2, iterator, function(err, res) {
462 * console.log(res); // [1, 5, 3]
463 * console.log(order); // [1, 3, 5, 2, 4]
464 * });
465 *
466 * @example
467 *
468 * // object with key
469 * var order = [];
470 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
471 * var iterator = function(num, key, done) {
472 * setTimeout(function() {
473 * order.push([num, key]);
474 * done(null, num % 2);
475 * }, num * 10);
476 * };
477 * async.filterLimit(object, 2, iterator, function(err, res) {
478 * console.log(res); // [1, 5, 3]
479 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
480 * });
481 *
482 */
483 var filterLimit = createFilterLimit(true);
484
485 /**
486 * @memberof async
487 * @namespace reject
488 * @param {Array|Object} collection
489 * @param {Function} iterator
490 * @param {Function} callback
491 * @example
492 *
493 * // array
494 * var order = [];
495 * var array = [1, 3, 2];
496 * var iterator = function(num, done) {
497 * setTimeout(function() {
498 * order.push(num);
499 * done(null, num % 2);
500 * }, num * 10);
501 * };
502 * async.reject(array, iterator, function(err, res) {
503 * console.log(res); // [2];
504 * console.log(order); // [1, 2, 3]
505 * });
506 *
507 * @example
508 *
509 * // array with index
510 * var order = [];
511 * var array = [1, 3, 2];
512 * var iterator = function(num, index, done) {
513 * setTimeout(function() {
514 * order.push([num, index]);
515 * done(null, num % 2);
516 * }, num * 10);
517 * };
518 * async.reject(array, iterator, function(err, res) {
519 * console.log(res); // [2];
520 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
521 * });
522 *
523 * @example
524 *
525 * // object
526 * var order = [];
527 * var object = { a: 1, b: 3, c: 2 };
528 * var iterator = function(num, done) {
529 * setTimeout(function() {
530 * order.push(num);
531 * done(null, num % 2);
532 * }, num * 10);
533 * };
534 * async.reject(object, iterator, function(err, res) {
535 * console.log(res); // [2];
536 * console.log(order); // [1, 2, 3]
537 * });
538 *
539 * @example
540 *
541 * // object with key
542 * var order = [];
543 * var object = { a: 1, b: 3, c: 2 };
544 * var iterator = function(num, key, done) {
545 * setTimeout(function() {
546 * order.push([num, key]);
547 * done(null, num % 2);
548 * }, num * 10);
549 * };
550 * async.reject(object, iterator, function(err, res) {
551 * console.log(res); // [2];
552 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
553 * });
554 *
555 */
556 var reject = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, false);
557
558 /**
559 * @memberof async
560 * @namespace rejectSeries
561 * @param {Array|Object} collection
562 * @param {Function} iterator
563 * @param {Function} callback
564 * @example
565 *
566 * // array
567 * var order = [];
568 * var array = [1, 3, 2];
569 * var iterator = function(num, done) {
570 * setTimeout(function() {
571 * order.push(num);
572 * done(null, num % 2);
573 * }, num * 10);
574 * };
575 * async.rejectSeries(array, iterator, function(err, res) {
576 * console.log(res); // [2];
577 * console.log(order); // [1, 3, 2]
578 * });
579 *
580 * @example
581 *
582 * // object
583 * var order = [];
584 * var object = { a: 1, b: 3, c: 2 };
585 * var iterator = function(num, done) {
586 * setTimeout(function() {
587 * order.push(num);
588 * done(null, num % 2);
589 * }, num * 10);
590 * };
591 * async.rejectSeries(object, iterator, function(err, res) {
592 * console.log(res); // [2];
593 * console.log(order); // [1, 3, 2]
594 * });
595 *
596 * @example
597 *
598 * // object with key
599 * var order = [];
600 * var object = { a: 1, b: 3, c: 2 };
601 * var iterator = function(num, key, done) {
602 * setTimeout(function() {
603 * order.push([num, key]);
604 * done(null, num % 2);
605 * }, num * 10);
606 * };
607 * async.rejectSeries(object, iterator, function(err, res) {
608 * console.log(res); // [2];
609 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
610 * });
611 *
612 */
613 var rejectSeries = createFilterSeries(false);
614
615 /**
616 * @memberof async
617 * @namespace rejectLimit
618 * @param {Array|Object} collection
619 * @param {number} limit - limit >= 1
620 * @param {Function} iterator
621 * @param {Function} callback
622 * @example
623 *
624 * // array
625 * var order = [];
626 * var array = [1, 5, 3, 4, 2];
627 * var iterator = function(num, done) {
628 * setTimeout(function() {
629 * order.push(num);
630 * done(null, num % 2);
631 * }, num * 10);
632 * };
633 * async.rejectLimit(array, 2, iterator, function(err, res) {
634 * console.log(res); // [4, 2]
635 * console.log(order); // [1, 3, 5, 2, 4]
636 * });
637 *
638 * @example
639 *
640 * // array with index
641 * var order = [];
642 * var array = [1, 5, 3, 4, 2];
643 * var iterator = function(num, index, done) {
644 * setTimeout(function() {
645 * order.push([num, index]);
646 * done(null, num % 2);
647 * }, num * 10);
648 * };
649 * async.rejectLimit(array, 2, iterator, function(err, res) {
650 * console.log(res); // [4, 2]
651 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
652 * });
653 *
654 * @example
655 *
656 * // object
657 * var order = [];
658 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
659 * var iterator = function(num, done) {
660 * setTimeout(function() {
661 * order.push(num);
662 * done(null, num % 2);
663 * }, num * 10);
664 * };
665 * async.rejectLimit(object, 2, iterator, function(err, res) {
666 * console.log(res); // [4, 2]
667 * console.log(order); // [1, 3, 5, 2, 4]
668 * });
669 *
670 * @example
671 *
672 * // object with key
673 * var order = [];
674 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
675 * var iterator = function(num, key, done) {
676 * setTimeout(function() {
677 * order.push([num, key]);
678 * done(null, num % 2);
679 * }, num * 10);
680 * };
681 * async.rejectLimit(object, 2, iterator, function(err, res) {
682 * console.log(res); // [4, 2]
683 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
684 * });
685 *
686 */
687 var rejectLimit = createFilterLimit(false);
688
689 /**
690 * @memberof async
691 * @namespace detect
692 * @param {Array|Object} collection
693 * @param {Function} iterator
694 * @param {Function} callback
695 * @example
696 *
697 * // array
698 * var order = [];
699 * var array = [1, 3, 2];
700 * var iterator = function(num, done) {
701 * setTimeout(function() {
702 * order.push(num);
703 * done(null, num % 2);
704 * }, num * 10);
705 * };
706 * async.detect(array, iterator, function(err, res) {
707 * console.log(res); // 1
708 * console.log(order); // [1]
709 * });
710 *
711 * @example
712 *
713 * // array with index
714 * var order = [];
715 * var array = [1, 3, 2];
716 * var iterator = function(num, index, done) {
717 * setTimeout(function() {
718 * order.push([num, index]);
719 * done(null, num % 2);
720 * }, num * 10);
721 * };
722 * async.detect(array, iterator, function(err, res) {
723 * console.log(res); // 1
724 * console.log(order); // [[1, 0]]
725 * });
726 *
727 * @example
728 *
729 * // object
730 * var order = [];
731 * var object = { a: 1, b: 3, c: 2 };
732 * var iterator = function(num, done) {
733 * setTimeout(function() {
734 * order.push(num);
735 * done(null, num % 2);
736 * }, num * 10);
737 * };
738 * async.detect(object, iterator, function(err, res) {
739 * console.log(res); // 1
740 * console.log(order); // [1]
741 * });
742 *
743 * @example
744 *
745 * // object with key
746 * var order = [];
747 * var object = { a: 1, b: 3, c: 2 };
748 * var iterator = function(num, key, done) {
749 * setTimeout(function() {
750 * order.push([num, key]);
751 * done(null, num % 2);
752 * }, num * 10);
753 * };
754 * async.detect(object, iterator, function(err, res) {
755 * console.log(res); // 1
756 * console.log(order); // [[1, 'a']]
757 * });
758 *
759 */
760 var detect = createDetect(arrayEachValue, baseEachValue, symbolEachValue, true);
761
762 /**
763 * @memberof async
764 * @namespace detectSeries
765 * @param {Array|Object} collection
766 * @param {Function} iterator
767 * @param {Function} callback
768 * @example
769 *
770 * // array
771 * var order = [];
772 * var array = [1, 3, 2];
773 * var iterator = function(num, done) {
774 * setTimeout(function() {
775 * order.push(num);
776 * done(null, num % 2);
777 * }, num * 10);
778 * };
779 * async.detectSeries(array, iterator, function(err, res) {
780 * console.log(res); // 1
781 * console.log(order); // [1]
782 * });
783 *
784 * @example
785 *
786 * // array with index
787 * var order = [];
788 * var array = [1, 3, 2];
789 * var iterator = function(num, index, done) {
790 * setTimeout(function() {
791 * order.push([num, index]);
792 * done(null, num % 2);
793 * }, num * 10);
794 * };
795 * async.detectSeries(array, iterator, function(err, res) {
796 * console.log(res); // 1
797 * console.log(order); // [[1, 0]]
798 * });
799 *
800 * @example
801 *
802 * // object
803 * var order = [];
804 * var object = { a: 1, b: 3, c: 2 };
805 * var iterator = function(num, done) {
806 * setTimeout(function() {
807 * order.push(num);
808 * done(null, num % 2);
809 * }, num * 10);
810 * };
811 * async.detectSeries(object, iterator, function(err, res) {
812 * console.log(res); // 1
813 * console.log(order); // [1]
814 * });
815 *
816 * @example
817 *
818 * // object with key
819 * var order = [];
820 * var object = { a: 1, b: 3, c: 2 };
821 * var iterator = function(num, key, done) {
822 * setTimeout(function() {
823 * order.push([num, key]);
824 * done(null, num % 2);
825 * }, num * 10);
826 * };
827 * async.detectSeries(object, iterator, function(err, res) {
828 * console.log(res); // 1
829 * console.log(order); // [[1, 'a']]
830 * });
831 *
832 */
833 var detectSeries = createDetectSeries(true);
834
835 /**
836 * @memberof async
837 * @namespace detectLimit
838 * @param {Array|Object} collection
839 * @param {number} limit - limit >= 1
840 * @param {Function} iterator
841 * @param {Function} callback
842 * @example
843 *
844 * // array
845 * var order = [];
846 * var array = [1, 5, 3, 4, 2];
847 * var iterator = function(num, done) {
848 * setTimeout(function() {
849 * order.push(num);
850 * done(null, num % 2);
851 * }, num * 10);
852 * };
853 * async.detectLimit(array, 2, iterator, function(err, res) {
854 * console.log(res); // 1
855 * console.log(order); // [1]
856 * });
857 *
858 * @example
859 *
860 * // array with index
861 * var order = [];
862 * var array = [1, 5, 3, 4, 2];
863 * var iterator = function(num, index, done) {
864 * setTimeout(function() {
865 * order.push([num, index]);
866 * done(null, num % 2);
867 * }, num * 10);
868 * };
869 * async.detectLimit(array, 2, iterator, function(err, res) {
870 * console.log(res); // 1
871 * console.log(order); // [[1, 0]]
872 * });
873 *
874 * @example
875 *
876 * // object
877 * var order = [];
878 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
879 * var iterator = function(num, done) {
880 * setTimeout(function() {
881 * order.push(num);
882 * done(null, num % 2);
883 * }, num * 10);
884 * };
885 * async.detectLimit(object, 2, iterator, function(err, res) {
886 * console.log(res); // 1
887 * console.log(order); // [1]
888 * });
889 *
890 * @example
891 *
892 * // object with key
893 * var order = [];
894 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
895 * var iterator = function(num, key, done) {
896 * setTimeout(function() {
897 * order.push([num, key]);
898 * done(null, num % 2);
899 * }, num * 10);
900 * };
901 * async.detectLimit(object, 2, iterator, function(err, res) {
902 * console.log(res); // 1
903 * console.log(order); // [[1, 'a']]
904 * });
905 *
906 */
907 var detectLimit = createDetectLimit(true);
908
909 /**
910 * @memberof async
911 * @namespace every
912 * @param {Array|Object} collection
913 * @param {Function} iterator
914 * @param {Function} callback
915 * @example
916 *
917 * // array
918 * var order = [];
919 * var array = [1, 3, 2];
920 * var iterator = function(num, done) {
921 * setTimeout(function() {
922 * order.push(num);
923 * done(null, num % 2);
924 * }, num * 10);
925 * };
926 * async.every(array, iterator, function(err, res) {
927 * console.log(res); // false
928 * console.log(order); // [1, 2]
929 * });
930 *
931 * @example
932 *
933 * // array with index
934 * var order = [];
935 * var array = [1, 3, 2];
936 * var iterator = function(num, index, done) {
937 * setTimeout(function() {
938 * order.push([num, index]);
939 * done(null, num % 2);
940 * }, num * 10);
941 * };
942 * async.every(array, iterator, function(err, res) {
943 * console.log(res); // false
944 * console.log(order); // [[1, 0], [2, 2]]
945 * });
946 *
947 * @example
948 *
949 * // object
950 * var order = [];
951 * var object = { a: 1, b: 3, c: 2 };
952 * var iterator = function(num, done) {
953 * setTimeout(function() {
954 * order.push(num);
955 * done(null, num % 2);
956 * }, num * 10);
957 * };
958 * async.every(object, iterator, function(err, res) {
959 * console.log(res); // false
960 * console.log(order); // [1, 2]
961 * });
962 *
963 * @example
964 *
965 * // object with key
966 * var order = [];
967 * var object = { a: 1, b: 3, c: 2 };
968 * var iterator = function(num, key, done) {
969 * setTimeout(function() {
970 * order.push([num, key]);
971 * done(null, num % 2);
972 * }, num * 10);
973 * };
974 * async.every(object, iterator, function(err, res) {
975 * console.log(res); // false
976 * console.log(order); // [[1, 'a'], [2, 'c']]
977 * });
978 *
979 */
980 var every = createEvery(arrayEachValue, baseEachValue, symbolEachValue);
981
982 /**
983 * @memberof async
984 * @namespace everySeries
985 * @param {Array|Object} collection
986 * @param {Function} iterator
987 * @param {Function} callback
988 * @example
989 *
990 * // array
991 * var order = [];
992 * var array = [1, 3, 2];
993 * var iterator = function(num, done) {
994 * setTimeout(function() {
995 * order.push(num);
996 * done(null, num % 2);
997 * }, num * 10);
998 * };
999 * async.everySeries(array, iterator, function(err, res) {
1000 * console.log(res); // false
1001 * console.log(order); // [1, 3, 2]
1002 * });
1003 *
1004 * @example
1005 *
1006 * // array with index
1007 * var order = [];
1008 * var array = [1, 3, 2];
1009 * var iterator = function(num, index, done) {
1010 * setTimeout(function() {
1011 * order.push([num, index]);
1012 * done(null, num % 2);
1013 * }, num * 10);
1014 * };
1015 * async.everySeries(array, iterator, function(err, res) {
1016 * console.log(res); // false
1017 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
1018 * });
1019 *
1020 * @example
1021 *
1022 * // object
1023 * var order = [];
1024 * var object = { a: 1, b: 3, c: 2 };
1025 * var iterator = function(num, done) {
1026 * setTimeout(function() {
1027 * order.push(num);
1028 * done(null, num % 2);
1029 * }, num * 10);
1030 * };
1031 * async.everySeries(object, iterator, function(err, res) {
1032 * console.log(res); // false
1033 * console.log(order); // [1, 3, 2]
1034 * });
1035 *
1036 * @example
1037 *
1038 * // object with key
1039 * var order = [];
1040 * var object = { a: 1, b: 3, c: 2 };
1041 * var iterator = function(num, key, done) {
1042 * setTimeout(function() {
1043 * order.push([num, key]);
1044 * done(null, num % 2);
1045 * }, num * 10);
1046 * };
1047 * async.everySeries(object, iterator, function(err, res) {
1048 * console.log(res); // false
1049 * console.log(order); // [[1, 'a'], [3, 'b'] [2, 'c']]
1050 * });
1051 *
1052 */
1053 var everySeries = createEverySeries();
1054
1055 /**
1056 * @memberof async
1057 * @namespace everyLimit
1058 * @param {Array|Object} collection
1059 * @param {number} limit - limit >= 1
1060 * @param {Function} iterator
1061 * @param {Function} callback
1062 * @example
1063 *
1064 * // array
1065 * var order = [];
1066 * var array = [1, 5, 3, 4, 2];
1067 * var iterator = function(num, done) {
1068 * setTimeout(function() {
1069 * order.push(num);
1070 * done(null, num % 2);
1071 * }, num * 10);
1072 * };
1073 * async.everyLimit(array, 2, iterator, function(err, res) {
1074 * console.log(res); // false
1075 * console.log(order); // [1, 3, 5, 2]
1076 * });
1077 *
1078 * @example
1079 *
1080 * // array with index
1081 * var order = [];
1082 * var array = [1, 5, 3, 4, 2];
1083 * var iterator = function(num, index, done) {
1084 * setTimeout(function() {
1085 * order.push([num, index]);
1086 * done(null, num % 2);
1087 * }, num * 10);
1088 * };
1089 * async.everyLimit(array, 2, iterator, function(err, res) {
1090 * console.log(res); // false
1091 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4]]
1092 * });
1093 *
1094 * @example
1095 *
1096 * // object
1097 * var order = [];
1098 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1099 * var iterator = function(num, done) {
1100 * setTimeout(function() {
1101 * order.push(num);
1102 * done(null, num % 2);
1103 * }, num * 10);
1104 * };
1105 * async.everyLimit(object, 2, iterator, function(err, res) {
1106 * console.log(res); // false
1107 * console.log(order); // [1, 3, 5, 2]
1108 * });
1109 *
1110 * @example
1111 *
1112 * // object with key
1113 * var order = [];
1114 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1115 * var iterator = function(num, key, done) {
1116 * setTimeout(function() {
1117 * order.push([num, key]);
1118 * done(null, num % 2);
1119 * }, num * 10);
1120 * };
1121 * async.everyLimit(object, 2, iterator, function(err, res) {
1122 * console.log(res); // false
1123 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e']]
1124 * });
1125 *
1126 */
1127 var everyLimit = createEveryLimit();
1128
1129 /**
1130 * @memberof async
1131 * @namespace pick
1132 * @param {Array|Object} collection
1133 * @param {Function} iterator
1134 * @param {Function} callback
1135 * @example
1136 *
1137 * // array
1138 * var order = [];
1139 * var array = [1, 3, 2, 4];
1140 * var iterator = function(num, done) {
1141 * setTimeout(function() {
1142 * order.push(num);
1143 * done(null, num % 2);
1144 * }, num * 10);
1145 * };
1146 * async.pick(array, iterator, function(err, res) {
1147 * console.log(res); // { '0': 1, '1': 3 }
1148 * console.log(order); // [1, 2, 3, 4]
1149 * });
1150 *
1151 * @example
1152 *
1153 * // array with index
1154 * var order = [];
1155 * var array = [1, 3, 2, 4];
1156 * var iterator = function(num, index, done) {
1157 * setTimeout(function() {
1158 * order.push([num, index]);
1159 * done(null, num % 2);
1160 * }, num * 10);
1161 * };
1162 * async.pick(array, iterator, function(err, res) {
1163 * console.log(res); // { '0': 1, '1': 3 }
1164 * console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]]
1165 * });
1166 *
1167 * @example
1168 *
1169 * // object
1170 * var order = [];
1171 * var object = { a: 1, b: 3, c: 2, d: 4 };
1172 * var iterator = function(num, done) {
1173 * setTimeout(function() {
1174 * order.push(num);
1175 * done(null, num % 2);
1176 * }, num * 10);
1177 * };
1178 * async.pick(object, iterator, function(err, res) {
1179 * console.log(res); // { a: 1, b: 3 }
1180 * console.log(order); // [1, 2, 3, 4]
1181 * });
1182 *
1183 * @example
1184 *
1185 * // object with key
1186 * var order = [];
1187 * var object = { a: 1, b: 3, c: 2, d: 4 };
1188 * var iterator = function(num, key, done) {
1189 * setTimeout(function() {
1190 * order.push([num, key]);
1191 * done(null, num % 2);
1192 * }, num * 10);
1193 * };
1194 * async.pick(object, iterator, function(err, res) {
1195 * console.log(res); // { a: 1, b: 3 }
1196 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
1197 * });
1198 *
1199 */
1200 var pick = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, true);
1201
1202 /**
1203 * @memberof async
1204 * @namespace pickSeries
1205 * @param {Array|Object} collection
1206 * @param {Function} iterator
1207 * @param {Function} callback
1208 * @example
1209 *
1210 * // array
1211 * var order = [];
1212 * var array = [1, 3, 2, 4];
1213 * var iterator = function(num, done) {
1214 * setTimeout(function() {
1215 * order.push(num);
1216 * done(null, num % 2);
1217 * }, num * 10);
1218 * };
1219 * async.pickSeries(array, iterator, function(err, res) {
1220 * console.log(res); // { '0': 1, '1': 3 }
1221 * console.log(order); // [1, 3, 2, 4]
1222 * });
1223 *
1224 * @example
1225 *
1226 * // array with index
1227 * var order = [];
1228 * var array = [1, 3, 2, 4];
1229 * var iterator = function(num, index, done) {
1230 * setTimeout(function() {
1231 * order.push([num, index]);
1232 * done(null, num % 2);
1233 * }, num * 10);
1234 * };
1235 * async.pickSeries(array, iterator, function(err, res) {
1236 * console.log(res); // { '0': 1, '1': 3 }
1237 * console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]]
1238 * });
1239 *
1240 * @example
1241 *
1242 * // object
1243 * var order = [];
1244 * var object = { a: 1, b: 3, c: 2, d: 4 };
1245 * var iterator = function(num, done) {
1246 * setTimeout(function() {
1247 * order.push(num);
1248 * done(null, num % 2);
1249 * }, num * 10);
1250 * };
1251 * async.pickSeries(object, iterator, function(err, res) {
1252 * console.log(res); // { a: 1, b: 3 }
1253 * console.log(order); // [1, 3, 2, 4]
1254 * });
1255 *
1256 * @example
1257 *
1258 * // object with key
1259 * var order = [];
1260 * var object = { a: 1, b: 3, c: 2, d: 4 };
1261 * var iterator = function(num, key, done) {
1262 * setTimeout(function() {
1263 * order.push([num, key]);
1264 * done(null, num % 2);
1265 * }, num * 10);
1266 * };
1267 * async.pickSeries(object, iterator, function(err, res) {
1268 * console.log(res); // { a: 1, b: 3 }
1269 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']]
1270 * });
1271 *
1272 */
1273 var pickSeries = createPickSeries(true);
1274
1275 /**
1276 * @memberof async
1277 * @namespace pickLimit
1278 * @param {Array|Object} collection
1279 * @param {number} limit - limit >= 1
1280 * @param {Function} iterator
1281 * @param {Function} callback
1282 * @example
1283 *
1284 * // array
1285 * var order = [];
1286 * var array = [1, 5, 3, 4, 2];
1287 * var iterator = function(num, done) {
1288 * setTimeout(function() {
1289 * order.push(num);
1290 * done(null, num % 2);
1291 * }, num * 10);
1292 * };
1293 * async.pickLimit(array, 2, iterator, function(err, res) {
1294 * console.log(res); // { '0': 1, '1': 5, '2': 3 }
1295 * console.log(order); // [1, 3, 5, 2, 4]
1296 * });
1297 *
1298 * @example
1299 *
1300 * // array with index
1301 * var order = [];
1302 * var array = [1, 5, 3, 4, 2];
1303 * var iterator = function(num, index, done) {
1304 * setTimeout(function() {
1305 * order.push([num, index]);
1306 * done(null, num % 2);
1307 * }, num * 10);
1308 * };
1309 * async.pickLimit(array, 2, iterator, function(err, res) {
1310 * console.log(res); // { '0': 1, '1': 5, '2': 3 }
1311 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
1312 * });
1313 *
1314 * @example
1315 *
1316 * // object
1317 * var order = [];
1318 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1319 * var iterator = function(num, done) {
1320 * setTimeout(function() {
1321 * order.push(num);
1322 * done(null, num % 2);
1323 * }, num * 10);
1324 * };
1325 * async.pickLimit(object, 2, iterator, function(err, res) {
1326 * console.log(res); // { a: 1, b: 5, c: 3 }
1327 * console.log(order); // [1, 3, 5, 2, 4]
1328 * });
1329 *
1330 * @example
1331 *
1332 * // object with key
1333 * var order = [];
1334 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1335 * var iterator = function(num, key, done) {
1336 * setTimeout(function() {
1337 * order.push([num, key]);
1338 * done(null, num % 2);
1339 * }, num * 10);
1340 * };
1341 * async.pickLimit(object, 2, iterator, function(err, res) {
1342 * console.log(res); // { a: 1, b: 5, c: 3 }
1343 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
1344 * });
1345 *
1346 */
1347 var pickLimit = createPickLimit(true);
1348
1349 /**
1350 * @memberof async
1351 * @namespace omit
1352 * @param {Array|Object} collection
1353 * @param {Function} iterator
1354 * @param {Function} callback
1355 * @example
1356 *
1357 * // array
1358 * var order = [];
1359 * var array = [1, 3, 2, 4];
1360 * var iterator = function(num, done) {
1361 * setTimeout(function() {
1362 * order.push(num);
1363 * done(null, num % 2);
1364 * }, num * 10);
1365 * };
1366 * async.omit(array, iterator, function(err, res) {
1367 * console.log(res); // { '2': 2, '3': 4 }
1368 * console.log(order); // [1, 2, 3, 4]
1369 * });
1370 *
1371 * @example
1372 *
1373 * // array with index
1374 * var order = [];
1375 * var array = [1, 3, 2, 4];
1376 * var iterator = function(num, index, done) {
1377 * setTimeout(function() {
1378 * order.push([num, index]);
1379 * done(null, num % 2);
1380 * }, num * 10);
1381 * };
1382 * async.omit(array, iterator, function(err, res) {
1383 * console.log(res); // { '2': 2, '3': 4 }
1384 * console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]]
1385 * });
1386 *
1387 * @example
1388 *
1389 * // object
1390 * var order = [];
1391 * var object = { a: 1, b: 3, c: 2, d: 4 };
1392 * var iterator = function(num, done) {
1393 * setTimeout(function() {
1394 * order.push(num);
1395 * done(null, num % 2);
1396 * }, num * 10);
1397 * };
1398 * async.omit(object, iterator, function(err, res) {
1399 * console.log(res); // { c: 2, d: 4 }
1400 * console.log(order); // [1, 2, 3, 4]
1401 * });
1402 *
1403 * @example
1404 *
1405 * // object with key
1406 * var order = [];
1407 * var object = { a: 1, b: 3, c: 2, d: 4 };
1408 * var iterator = function(num, key, done) {
1409 * setTimeout(function() {
1410 * order.push([num, key]);
1411 * done(null, num % 2);
1412 * }, num * 10);
1413 * };
1414 * async.omit(object, iterator, function(err, res) {
1415 * console.log(res); // { c: 2, d: 4 }
1416 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
1417 * });
1418 *
1419 */
1420 var omit = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, false);
1421
1422 /**
1423 * @memberof async
1424 * @namespace omitSeries
1425 * @param {Array|Object} collection
1426 * @param {Function} iterator
1427 * @param {Function} callback
1428 * @example
1429 *
1430 * // array
1431 * var order = [];
1432 * var array = [1, 3, 2, 4];
1433 * var iterator = function(num, done) {
1434 * setTimeout(function() {
1435 * order.push(num);
1436 * done(null, num % 2);
1437 * }, num * 10);
1438 * };
1439 * async.omitSeries(array, iterator, function(err, res) {
1440 * console.log(res); // { '2': 2, '3': 4 }
1441 * console.log(order); // [1, 3, 2, 4]
1442 * });
1443 *
1444 * @example
1445 *
1446 * // array with index
1447 * var order = [];
1448 * var array = [1, 3, 2, 4];
1449 * var iterator = function(num, index, done) {
1450 * setTimeout(function() {
1451 * order.push([num, index]);
1452 * done(null, num % 2);
1453 * }, num * 10);
1454 * };
1455 * async.omitSeries(array, iterator, function(err, res) {
1456 * console.log(res); // { '2': 2, '3': 4 }
1457 * console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]]
1458 * });
1459 *
1460 * @example
1461 *
1462 * // object
1463 * var order = [];
1464 * var object = { a: 1, b: 3, c: 2, d: 4 };
1465 * var iterator = function(num, done) {
1466 * setTimeout(function() {
1467 * order.push(num);
1468 * done(null, num % 2);
1469 * }, num * 10);
1470 * };
1471 * async.omitSeries(object, iterator, function(err, res) {
1472 * console.log(res); // { c: 2, d: 4 }
1473 * console.log(order); // [1, 3, 2, 4]
1474 * });
1475 *
1476 * @example
1477 *
1478 * // object with key
1479 * var order = [];
1480 * var object = { a: 1, b: 3, c: 2, d: 4 };
1481 * var iterator = function(num, key, done) {
1482 * setTimeout(function() {
1483 * order.push([num, key]);
1484 * done(null, num % 2);
1485 * }, num * 10);
1486 * };
1487 * async.omitSeries(object, iterator, function(err, res) {
1488 * console.log(res); // { c: 2, d: 4 }
1489 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']]
1490 * });
1491 *
1492 */
1493 var omitSeries = createPickSeries(false);
1494
1495 /**
1496 * @memberof async
1497 * @namespace omitLimit
1498 * @param {Array|Object} collection
1499 * @param {number} limit - limit >= 1
1500 * @param {Function} iterator
1501 * @param {Function} callback
1502 * @example
1503 *
1504 * // array
1505 * var order = [];
1506 * var array = [1, 5, 3, 4, 2];
1507 * var iterator = function(num, done) {
1508 * setTimeout(function() {
1509 * order.push(num);
1510 * done(null, num % 2);
1511 * }, num * 10);
1512 * };
1513 * async.omitLimit(array, 2, iterator, function(err, res) {
1514 * console.log(res); // { '3': 4, '4': 2 }
1515 * console.log(order); // [1, 3, 5, 2, 4]
1516 * });
1517 *
1518 * @example
1519 *
1520 * // array with index
1521 * var order = [];
1522 * var array = [1, 5, 3, 4, 2];
1523 * var iterator = function(num, index, done) {
1524 * setTimeout(function() {
1525 * order.push([num, index]);
1526 * done(null, num % 2);
1527 * }, num * 10);
1528 * };
1529 * async.omitLimit(array, 2, iterator, function(err, res) {
1530 * console.log(res); // { '3': 4, '4': 2 }
1531 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
1532 * });
1533 *
1534 * @example
1535 *
1536 * // object
1537 * var order = [];
1538 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1539 * var iterator = function(num, done) {
1540 * setTimeout(function() {
1541 * order.push(num);
1542 * done(null, num % 2);
1543 * }, num * 10);
1544 * };
1545 * async.omitLimit(object, 2, iterator, function(err, res) {
1546 * console.log(res); // { d: 4, e: 2 }
1547 * console.log(order); // [1, 3, 5, 2, 4]
1548 * });
1549 *
1550 * @example
1551 *
1552 * // object with key
1553 * var order = [];
1554 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
1555 * var iterator = function(num, key, done) {
1556 * setTimeout(function() {
1557 * order.push([num, key]);
1558 * done(null, num % 2);
1559 * }, num * 10);
1560 * };
1561 * async.omitLimit(object, 2, iterator, function(err, res) {
1562 * console.log(res); // { d: 4, e: 2 }
1563 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
1564 * });
1565 *
1566 */
1567 var omitLimit = createPickLimit(false);
1568
1569 /**
1570 * @memberof async
1571 * @namespace transform
1572 * @param {Array|Object} collection
1573 * @param {Array|Object|Function} [accumulator]
1574 * @param {Function} [iterator]
1575 * @param {Function} [callback]
1576 * @example
1577 *
1578 * // array
1579 * var order = [];
1580 * var collection = [1, 3, 2, 4];
1581 * var iterator = function(result, num, done) {
1582 * setTimeout(function() {
1583 * order.push(num);
1584 * result.push(num)
1585 * done();
1586 * }, num * 10);
1587 * };
1588 * async.transform(collection, iterator, function(err, res) {
1589 * console.log(res); // [1, 2, 3, 4]
1590 * console.log(order); // [1, 2, 3, 4]
1591 * });
1592 *
1593 * @example
1594 *
1595 * // array with index and accumulator
1596 * var order = [];
1597 * var collection = [1, 3, 2, 4];
1598 * var iterator = function(result, num, index, done) {
1599 * setTimeout(function() {
1600 * order.push([num, index]);
1601 * result[index] = num;
1602 * done();
1603 * }, num * 10);
1604 * };
1605 * async.transform(collection, {}, iterator, function(err, res) {
1606 * console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 }
1607 * console.log(order); // [[1, 0], [2, 2], [3, 1], [4, 3]]
1608 * });
1609 *
1610 * @example
1611 *
1612 * // object with accumulator
1613 * var order = [];
1614 * var object = { a: 1, b: 3, c: 2, d: 4 };
1615 * var iterator = function(result, num, done) {
1616 * setTimeout(function() {
1617 * order.push(num);
1618 * result.push(num);
1619 * done();
1620 * }, num * 10);
1621 * };
1622 * async.transform(collection, [], iterator, function(err, res) {
1623 * console.log(res); // [1, 2, 3, 4]
1624 * console.log(order); // [1, 2, 3, 4]
1625 * });
1626 *
1627 * @example
1628 *
1629 * // object with key
1630 * var order = [];
1631 * var object = { a: 1, b: 3, c: 2, d: 4 };
1632 * var iterator = function(result, num, key, done) {
1633 * setTimeout(function() {
1634 * order.push([num, key]);
1635 * result[key] = num;
1636 * done();
1637 * }, num * 10);
1638 * };
1639 * async.transform(collection, iterator, function(err, res) {
1640 * console.log(res); // { a: 1, b: 3, c: 2, d: 4 }
1641 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
1642 * });
1643 *
1644 */
1645 var transform = createTransform(arrayEachResult, baseEachResult, symbolEachResult);
1646
1647 /**
1648 * @memberof async
1649 * @namespace sortBy
1650 * @param {Array|Object} collection
1651 * @param {Function} iterator
1652 * @param {Function} callback
1653 * @example
1654 *
1655 * // array
1656 * var order = [];
1657 * var array = [1, 3, 2];
1658 * var iterator = function(num, done) {
1659 * setTimeout(function() {
1660 * order.push(num);
1661 * done(null, num);
1662 * }, num * 10);
1663 * };
1664 * async.sortBy(array, iterator, function(err, res) {
1665 * console.log(res); // [1, 2, 3];
1666 * console.log(order); // [1, 2, 3]
1667 * });
1668 *
1669 * @example
1670 *
1671 * // array with index
1672 * var order = [];
1673 * var array = [1, 3, 2];
1674 * var iterator = function(num, index, done) {
1675 * setTimeout(function() {
1676 * order.push([num, index]);
1677 * done(null, num);
1678 * }, num * 10);
1679 * };
1680 * async.sortBy(array, iterator, function(err, res) {
1681 * console.log(res); // [1, 2, 3]
1682 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
1683 * });
1684 *
1685 * @example
1686 *
1687 * // object
1688 * var order = [];
1689 * var object = { a: 1, b: 3, c: 2 };
1690 * var iterator = function(num, done) {
1691 * setTimeout(function() {
1692 * order.push(num);
1693 * done(null, num);
1694 * }, num * 10);
1695 * };
1696 * async.sortBy(object, iterator, function(err, res) {
1697 * console.log(res); // [1, 2, 3]
1698 * console.log(order); // [1, 2, 3]
1699 * });
1700 *
1701 * @example
1702 *
1703 * // object with key
1704 * var order = [];
1705 * var object = { a: 1, b: 3, c: 2 };
1706 * var iterator = function(num, key, done) {
1707 * setTimeout(function() {
1708 * order.push([num, key]);
1709 * done(null, num);
1710 * }, num * 10);
1711 * };
1712 * async.sortBy(object, iterator, function(err, res) {
1713 * console.log(res); // [1, 2, 3]
1714 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
1715 * });
1716 *
1717 */
1718 var sortBy = createSortBy(arrayEachValue, baseEachValue, symbolEachValue);
1719
1720 /**
1721 * @memberof async
1722 * @namespace concat
1723 * @param {Array|Object} collection
1724 * @param {Function} iterator
1725 * @param {Function} callback
1726 * @example
1727 *
1728 * // array
1729 * var order = [];
1730 * var array = [1, 3, 2];
1731 * var iterator = function(num, done) {
1732 * setTimeout(function() {
1733 * order.push(num);
1734 * done(null, [num]);
1735 * }, num * 10);
1736 * };
1737 * async.concat(array, iterator, function(err, res) {
1738 * console.log(res); // [1, 2, 3];
1739 * console.log(order); // [1, 2, 3]
1740 * });
1741 *
1742 * @example
1743 *
1744 * // array with index
1745 * var order = [];
1746 * var array = [1, 3, 2];
1747 * var iterator = function(num, index, done) {
1748 * setTimeout(function() {
1749 * order.push([num, index]);
1750 * done(null, [num]);
1751 * }, num * 10);
1752 * };
1753 * async.concat(array, iterator, function(err, res) {
1754 * console.log(res); // [1, 2, 3]
1755 * console.log(order); // [[1, 0], [2, 2], [3, 1]]
1756 * });
1757 *
1758 * @example
1759 *
1760 * // object
1761 * var order = [];
1762 * var object = { a: 1, b: 3, c: 2 };
1763 * var iterator = function(num, done) {
1764 * setTimeout(function() {
1765 * order.push(num);
1766 * done(null, [num]);
1767 * }, num * 10);
1768 * };
1769 * async.concat(object, iterator, function(err, res) {
1770 * console.log(res); // [1, 2, 3]
1771 * console.log(order); // [1, 2, 3]
1772 * });
1773 *
1774 * @example
1775 *
1776 * // object with key
1777 * var order = [];
1778 * var object = { a: 1, b: 3, c: 2 };
1779 * var iterator = function(num, key, done) {
1780 * setTimeout(function() {
1781 * order.push([num, key]);
1782 * done(null, [num]);
1783 * }, num * 10);
1784 * };
1785 * async.concat(object, iterator, function(err, res) {
1786 * console.log(res); // [1, 2, 3]
1787 * console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
1788 * });
1789 *
1790 */
1791 var concat = createConcat(arrayEachIndex, baseEachIndex, symbolEachIndex);
1792
1793 /**
1794 * @memberof async
1795 * @namespace groupBy
1796 * @param {Array|Object} collection
1797 * @param {Function} iterator
1798 * @param {Function} callback
1799 * @example
1800 *
1801 * // array
1802 * var order = [];
1803 * var array = [4.2, 6.4, 6.1];
1804 * var iterator = function(num, done) {
1805 * setTimeout(function() {
1806 * order.push(num);
1807 * done(null, Math.floor(num));
1808 * }, num * 10);
1809 * };
1810 * async.groupBy(array, iterator, function(err, res) {
1811 * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1812 * console.log(order); // [4.2, 6.1, 6.4]
1813 * });
1814 *
1815 * @example
1816 *
1817 * // array with index
1818 * var order = [];
1819 * var array = [4.2, 6.4, 6.1];
1820 * var iterator = function(num, index, done) {
1821 * setTimeout(function() {
1822 * order.push([num, index]);
1823 * done(null, Math.floor(num));
1824 * }, num * 10);
1825 * };
1826 * async.groupBy(array, iterator, function(err, res) {
1827 * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1828 * console.log(order); // [[4.2, 0], [6.1, 2], [6.4, 1]]
1829 * });
1830 *
1831 * @example
1832 *
1833 * // object
1834 * var order = [];
1835 * var object = { a: 4.2, b: 6.4, c: 6.1 };
1836 * var iterator = function(num, done) {
1837 * setTimeout(function() {
1838 * order.push(num);
1839 * done(null, Math.floor(num));
1840 * }, num * 10);
1841 * };
1842 * async.groupBy(object, iterator, function(err, res) {
1843 * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1844 * console.log(order); // [4.2, 6.1, 6.4]
1845 * });
1846 *
1847 * @example
1848 *
1849 * // object with key
1850 * var order = [];
1851 * var object = { a: 4.2, b: 6.4, c: 6.1 };
1852 * var iterator = function(num, key, done) {
1853 * setTimeout(function() {
1854 * order.push([num, key]);
1855 * done(null, Math.floor(num));
1856 * }, num * 10);
1857 * };
1858 * async.groupBy(object, iterator, function(err, res) {
1859 * console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
1860 * console.log(order); // [[4.2, 'a'], [6.1, 'c'], [6.4, 'b']]
1861 * });
1862 *
1863 */
1864 var groupBy = createGroupBy(arrayEachValue, baseEachValue, symbolEachValue);
1865
1866 /**
1867 * @memberof async
1868 * @namespace parallel
1869 * @param {Array|Object} tasks - functions
1870 * @param {Function} callback
1871 * @example
1872 *
1873 * var order = [];
1874 * var tasks = [
1875 * function(done) {
1876 * setTimeout(function() {
1877 * order.push(1);
1878 * done(null, 1);
1879 * }, 10);
1880 * },
1881 * function(done) {
1882 * setTimeout(function() {
1883 * order.push(2);
1884 * done(null, 2);
1885 * }, 30);
1886 * },
1887 * function(done) {
1888 * setTimeout(function() {
1889 * order.push(3);
1890 * done(null, 3);
1891 * }, 40);
1892 * },
1893 * function(done) {
1894 * setTimeout(function() {
1895 * order.push(4);
1896 * done(null, 4);
1897 * }, 20);
1898 * }
1899 * ];
1900 * async.parallel(tasks, function(err, res) {
1901 * console.log(res); // [1, 2, 3, 4];
1902 * console.log(order); // [1, 4, 2, 3]
1903 * });
1904 *
1905 * @example
1906 *
1907 * var order = [];
1908 * var tasks = {
1909 * 'a': function(done) {
1910 * setTimeout(function() {
1911 * order.push(1);
1912 * done(null, 1);
1913 * }, 10);
1914 * },
1915 * 'b': function(done) {
1916 * setTimeout(function() {
1917 * order.push(2);
1918 * done(null, 2);
1919 * }, 30);
1920 * },
1921 * 'c': function(done) {
1922 * setTimeout(function() {
1923 * order.push(3);
1924 * done(null, 3);
1925 * }, 40);
1926 * },
1927 * 'd': function(done) {
1928 * setTimeout(function() {
1929 * order.push(4);
1930 * done(null, 4);
1931 * }, 20);
1932 * }
1933 * };
1934 * async.parallel(tasks, function(err, res) {
1935 * console.log(res); // { a: 1, b: 2, c: 3, d:4 }
1936 * console.log(order); // [1, 4, 2, 3]
1937 * });
1938 *
1939 */
1940 var parallel = createParallel(arrayEachFunc, baseEachFunc);
1941
1942 /**
1943 * @memberof async
1944 * @namespace applyEach
1945 */
1946 var applyEach = createApplyEach(map);
1947
1948 /**
1949 * @memberof async
1950 * @namespace applyEachSeries
1951 */
1952 var applyEachSeries = createApplyEach(mapSeries);
1953
1954 /**
1955 * @memberof async
1956 * @namespace log
1957 */
1958 var log = createLogger('log');
1959
1960 /**
1961 * @memberof async
1962 * @namespace dir
1963 */
1964 var dir = createLogger('dir');
1965
1966 /**
1967 * @version 2.5.0
1968 * @namespace async
1969 */
1970 var index = {
1971 VERSION: '2.5.0',
1972
1973 // Collections
1974 each: each,
1975 eachSeries: eachSeries,
1976 eachLimit: eachLimit,
1977 forEach: each,
1978 forEachSeries: eachSeries,
1979 forEachLimit: eachLimit,
1980 eachOf: each,
1981 eachOfSeries: eachSeries,
1982 eachOfLimit: eachLimit,
1983 forEachOf: each,
1984 forEachOfSeries: eachSeries,
1985 forEachOfLimit: eachLimit,
1986 map: map,
1987 mapSeries: mapSeries,
1988 mapLimit: mapLimit,
1989 mapValues: mapValues,
1990 mapValuesSeries: mapValuesSeries,
1991 mapValuesLimit: mapValuesLimit,
1992 filter: filter,
1993 filterSeries: filterSeries,
1994 filterLimit: filterLimit,
1995 select: filter,
1996 selectSeries: filterSeries,
1997 selectLimit: filterLimit,
1998 reject: reject,
1999 rejectSeries: rejectSeries,
2000 rejectLimit: rejectLimit,
2001 detect: detect,
2002 detectSeries: detectSeries,
2003 detectLimit: detectLimit,
2004 find: detect,
2005 findSeries: detectSeries,
2006 findLimit: detectLimit,
2007 pick: pick,
2008 pickSeries: pickSeries,
2009 pickLimit: pickLimit,
2010 omit: omit,
2011 omitSeries: omitSeries,
2012 omitLimit: omitLimit,
2013 reduce: reduce,
2014 inject: reduce,
2015 foldl: reduce,
2016 reduceRight: reduceRight,
2017 foldr: reduceRight,
2018 transform: transform,
2019 transformSeries: transformSeries,
2020 transformLimit: transformLimit,
2021 sortBy: sortBy,
2022 sortBySeries: sortBySeries,
2023 sortByLimit: sortByLimit,
2024 some: some,
2025 someSeries: someSeries,
2026 someLimit: someLimit,
2027 any: some,
2028 anySeries: someSeries,
2029 anyLimit: someLimit,
2030 every: every,
2031 everySeries: everySeries,
2032 everyLimit: everyLimit,
2033 all: every,
2034 allSeries: everySeries,
2035 allLimit: everyLimit,
2036 concat: concat,
2037 concatSeries: concatSeries,
2038 concatLimit: concatLimit,
2039 groupBy: groupBy,
2040 groupBySeries: groupBySeries,
2041 groupByLimit: groupByLimit,
2042
2043 // Control Flow
2044 parallel: parallel,
2045 series: series,
2046 parallelLimit: parallelLimit,
2047 tryEach: tryEach,
2048 waterfall: waterfall,
2049 angelFall: angelFall,
2050 angelfall: angelFall,
2051 whilst: whilst,
2052 doWhilst: doWhilst,
2053 until: until,
2054 doUntil: doUntil,
2055 during: during,
2056 doDuring: doDuring,
2057 forever: forever,
2058 compose: compose,
2059 seq: seq,
2060 applyEach: applyEach,
2061 applyEachSeries: applyEachSeries,
2062 queue: queue,
2063 priorityQueue: priorityQueue,
2064 cargo: cargo,
2065 auto: auto,
2066 autoInject: autoInject,
2067 retry: retry,
2068 retryable: retryable,
2069 iterator: iterator,
2070 times: times,
2071 timesSeries: timesSeries,
2072 timesLimit: timesLimit,
2073 race: race,
2074
2075 // Utils
2076 apply: apply,
2077 nextTick: asyncNextTick,
2078 setImmediate: asyncSetImmediate,
2079 memoize: memoize,
2080 unmemoize: unmemoize,
2081 ensureAsync: ensureAsync,
2082 constant: constant,
2083 asyncify: asyncify,
2084 wrapSync: asyncify,
2085 log: log,
2086 dir: dir,
2087 reflect: reflect,
2088 reflectAll: reflectAll,
2089 timeout: timeout,
2090 createLogger: createLogger,
2091
2092 // Mode
2093 safe: safe,
2094 fast: fast
2095 };
2096
2097 exports['default'] = index;
2098 baseEachSync(index, function(func, key) {
2099 exports[key] = func;
2100 }, nativeKeys(index));
2101
2102 /**
2103 * @private
2104 */
2105 function createImmediate(safeMode) {
2106 var delay = function delay(fn) {
2107 var args = slice(arguments, 1);
2108 setTimeout(function() {
2109 fn.apply(null, args);
2110 });
2111 };
2112 asyncSetImmediate = typeof setImmediate === func ? setImmediate : delay;
2113 if (typeof process === obj && typeof process.nextTick === func) {
2114 nextTick = /^v0.10/.test(process.version) ? asyncSetImmediate : process.nextTick;
2115 asyncNextTick = /^v0/.test(process.version) ? asyncSetImmediate : process.nextTick;
2116 } else {
2117 asyncNextTick = nextTick = asyncSetImmediate;
2118 }
2119 if (safeMode === false) {
2120 nextTick = function(cb) {
2121 cb();
2122 };
2123 }
2124 }
2125
2126 /* sync functions based on lodash */
2127
2128 /**
2129 * Converts `arguments` to an array.
2130 *
2131 * @private
2132 * @param {Array} array = The array to slice.
2133 */
2134 function createArray(array) {
2135 var index = -1;
2136 var size = array.length;
2137 var result = Array(size);
2138
2139 while (++index < size) {
2140 result[index] = array[index];
2141 }
2142 return result;
2143 }
2144
2145 /**
2146 * Create an array from `start`
2147 *
2148 * @private
2149 * @param {Array} array - The array to slice.
2150 * @param {number} start - The start position.
2151 */
2152 function slice(array, start) {
2153 var end = array.length;
2154 var index = -1;
2155 var size = end - start;
2156 if (size <= 0) {
2157 return [];
2158 }
2159 var result = Array(size);
2160
2161 while (++index < size) {
2162 result[index] = array[index + start];
2163 }
2164 return result;
2165 }
2166
2167 /**
2168 * @private
2169 * @param {Object} object
2170 */
2171 function objectClone(object) {
2172 var keys = nativeKeys(object);
2173 var size = keys.length;
2174 var index = -1;
2175 var result = {};
2176
2177 while (++index < size) {
2178 var key = keys[index];
2179 result[key] = object[key];
2180 }
2181 return result;
2182 }
2183
2184
2185 /**
2186 * Create an array with all falsey values removed.
2187 *
2188 * @private
2189 * @param {Array} array - The array to compact.
2190 */
2191 function compact(array) {
2192 var index = -1;
2193 var size = array.length;
2194 var result = [];
2195
2196 while (++index < size) {
2197 var value = array[index];
2198 if (value) {
2199 result[result.length] = value;
2200 }
2201 }
2202 return result;
2203 }
2204
2205 /**
2206 * Create an array of reverse sequence.
2207 *
2208 * @private
2209 * @param {Array} array - The array to reverse.
2210 */
2211 function reverse(array) {
2212 var index = -1;
2213 var size = array.length;
2214 var result = Array(size);
2215 var resIndex = size;
2216
2217 while (++index < size) {
2218 result[--resIndex] = array[index];
2219 }
2220 return result;
2221 }
2222
2223 /**
2224 * Checks if key exists in object property.
2225 *
2226 * @private
2227 * @param {Object} object - The object to inspect.
2228 * @param {string} key - The key to check.
2229 */
2230 function has(object, key) {
2231 return object.hasOwnProperty(key);
2232 }
2233
2234 /**
2235 * Check if target exists in array.
2236 * @private
2237 * @param {Array} array
2238 * @param {*} target
2239 */
2240 function notInclude(array, target) {
2241 var index = -1;
2242 var size = array.length;
2243
2244 while(++index < size) {
2245 if (array[index] === target) {
2246 return false;
2247 }
2248 }
2249 return true;
2250 }
2251
2252 /**
2253 * @private
2254 * @param {Array} array - The array to iterate over.
2255 * @param {Function} iterator - The function invoked per iteration.
2256 */
2257 function arrayEachSync(array, iterator) {
2258 var index = -1;
2259 var size = array.length;
2260
2261 while (++index < size) {
2262 iterator(array[index], index);
2263 }
2264 return array;
2265 }
2266
2267 /**
2268 * @private
2269 * @param {Object} object - The object to iterate over.
2270 * @param {Function} iterator - The function invoked per iteration.
2271 * @param {Array} keys
2272 */
2273 function baseEachSync(object, iterator, keys) {
2274 var index = -1;
2275 var size = keys.length;
2276
2277 while (++index < size) {
2278 var key = keys[index];
2279 iterator(object[key], key);
2280 }
2281 return object;
2282 }
2283
2284 /**
2285 * @private
2286 * @param {number} n
2287 * @param {Function} iterator
2288 */
2289 function timesSync(n, iterator) {
2290 var index = -1;
2291 while (++index < n) {
2292 iterator(index);
2293 }
2294 }
2295
2296 /**
2297 * @private
2298 * @param {Array} array
2299 * @param {string} key
2300 */
2301 function pluck(array, key) {
2302 var index = -1;
2303 var size = array.length;
2304 var result = Array(size);
2305
2306 while (++index < size) {
2307 var item = array[index] || {};
2308 result[index] = item[key];
2309 }
2310 return result;
2311 }
2312
2313 /**
2314 * @private
2315 * @param {Object} a
2316 * @param {Object} b
2317 */
2318 function sortIterator(a, b) {
2319 return a.criteria - b.criteria;
2320 }
2321
2322 /**
2323 * @Private
2324 */
2325 function makeConcatResult(array) {
2326 var result = [];
2327 arrayEachSync(array, function(value) {
2328 if (value === noop) {
2329 return;
2330 }
2331 if (isArray(value)) {
2332 nativePush.apply(result, value);
2333 } else {
2334 result.push(value);
2335 }
2336 });
2337 return result;
2338 }
2339
2340 /* async functions */
2341
2342 /**
2343 * @private
2344 */
2345 function arrayEach(array, iterator, callback) {
2346 var index = -1;
2347 var size = array.length;
2348
2349 if (iterator.length === 3) {
2350 while (++index < size) {
2351 iterator(array[index], index, onlyOnce(callback));
2352 }
2353 } else {
2354 while (++index < size) {
2355 iterator(array[index], onlyOnce(callback));
2356 }
2357 }
2358 }
2359
2360 /**
2361 * @private
2362 */
2363 function baseEach(object, iterator, callback, keys) {
2364 var key;
2365 var index = -1;
2366 var size = keys.length;
2367
2368 if (iterator.length === 3) {
2369 while (++index < size) {
2370 key = keys[index];
2371 iterator(object[key], key, onlyOnce(callback));
2372 }
2373 } else {
2374 while (++index < size) {
2375 iterator(object[keys[index]], onlyOnce(callback));
2376 }
2377 }
2378 }
2379
2380 /**
2381 * @private
2382 */
2383 function symbolEach(collection, iterator, callback) {
2384 var iter = collection[iteratorSymbol]();
2385 var index = -1;
2386 var item;
2387 if (iterator.length === 3) {
2388 while ((item = iter.next()).done === false) {
2389 iterator(item.value, ++index, onlyOnce(callback));
2390 }
2391 } else {
2392 while ((item = iter.next()).done === false) {
2393 iterator(item.value, onlyOnce(callback));
2394 }
2395 }
2396 }
2397
2398 /**
2399 * @private
2400 */
2401 function arrayEachResult(array, result, iterator, callback) {
2402 var index = -1;
2403 var size = array.length;
2404
2405 if (iterator.length === 4) {
2406 while (++index < size) {
2407 iterator(result, array[index], index, onlyOnce(callback));
2408 }
2409 } else {
2410 while (++index < size) {
2411 iterator(result, array[index], onlyOnce(callback));
2412 }
2413 }
2414 }
2415
2416 /**
2417 * @private
2418 */
2419 function baseEachResult(object, result, iterator, callback, keys) {
2420 var key;
2421 var index = -1;
2422 var size = keys.length;
2423
2424 if (iterator.length === 4) {
2425 while (++index < size) {
2426 key = keys[index];
2427 iterator(result, object[key], key, onlyOnce(callback));
2428 }
2429 } else {
2430 while (++index < size) {
2431 iterator(result, object[keys[index]], onlyOnce(callback));
2432 }
2433 }
2434 }
2435
2436 /**
2437 * @private
2438 */
2439 function symbolEachResult(collection, result, iterator, callback) {
2440 var item;
2441 var index = -1;
2442 var iter = collection[iteratorSymbol]();
2443
2444 if (iterator.length === 4) {
2445 while ((item = iter.next()).done === false) {
2446 iterator(result, item.value, ++index, onlyOnce(callback));
2447 }
2448 } else {
2449 while ((item = iter.next()).done === false) {
2450 iterator(result, item.value, onlyOnce(callback));
2451 }
2452 }
2453 }
2454
2455 /**
2456 * @private
2457 */
2458 function arrayEachFunc(array, createCallback) {
2459 var index = -1;
2460 var size = array.length;
2461
2462 while (++index < size) {
2463 array[index](createCallback(index));
2464 }
2465 }
2466
2467 /**
2468 * @private
2469 */
2470 function baseEachFunc(object, createCallback, keys) {
2471 var key;
2472 var index = -1;
2473 var size = keys.length;
2474
2475 while (++index < size) {
2476 key = keys[index];
2477 object[key](createCallback(key));
2478 }
2479 }
2480
2481 /**
2482 * @private
2483 */
2484 function arrayEachIndex(array, iterator, createCallback) {
2485 var index = -1;
2486 var size = array.length;
2487
2488 if (iterator.length === 3) {
2489 while (++index < size) {
2490 iterator(array[index], index, createCallback(index));
2491 }
2492 } else {
2493 while (++index < size) {
2494 iterator(array[index], createCallback(index));
2495 }
2496 }
2497 }
2498
2499 /**
2500 * @private
2501 */
2502 function baseEachIndex(object, iterator, createCallback, keys) {
2503 var key;
2504 var index = -1;
2505 var size = keys.length;
2506
2507 if (iterator.length === 3) {
2508 while (++index < size) {
2509 key = keys[index];
2510 iterator(object[key], key, createCallback(index));
2511 }
2512 } else {
2513 while (++index < size) {
2514 iterator(object[keys[index]], createCallback(index));
2515 }
2516 }
2517 }
2518
2519 /**
2520 * @private
2521 */
2522 function symbolEachIndex(collection, iterator, createCallback) {
2523 var values;
2524 var index = -1;
2525 var size = collection.size;
2526 var iter = collection[iteratorSymbol]();
2527
2528 if (iterator.length === 3) {
2529 while (++index < size) {
2530 values = iter.next().value;
2531 iterator(values, index, createCallback(index));
2532 }
2533 } else {
2534 while (++index < size) {
2535 iterator(iter.next().value, createCallback(index));
2536 }
2537 }
2538 }
2539
2540 /**
2541 * @private
2542 */
2543 function baseEachKey(object, iterator, createCallback, keys) {
2544 var key;
2545 var index = -1;
2546 var size = keys.length;
2547
2548 if (iterator.length === 3) {
2549 while (++index < size) {
2550 key = keys[index];
2551 iterator(object[key], key, createCallback(key));
2552 }
2553 } else {
2554 while (++index < size) {
2555 key = keys[index];
2556 iterator(object[key], createCallback(key));
2557 }
2558 }
2559 }
2560
2561 /**
2562 * @private
2563 */
2564 function symbolEachKey(collection, iterator, createCallback) {
2565 var item;
2566 var index = -1;
2567 var iter = collection[iteratorSymbol]();
2568
2569 if (iterator.length === 3) {
2570 while ((item = iter.next()).done === false) {
2571 iterator(item.value, ++index, createCallback(index));
2572 }
2573 } else {
2574 while ((item = iter.next()).done === false) {
2575 iterator(item.value, createCallback(++index));
2576 }
2577 }
2578 }
2579
2580 /**
2581 * @private
2582 */
2583 function arrayEachValue(array, iterator, createCallback) {
2584 var value;
2585 var index = -1;
2586 var size = array.length;
2587
2588 if (iterator.length === 3) {
2589 while (++index < size) {
2590 value = array[index];
2591 iterator(value, index, createCallback(value));
2592 }
2593 } else {
2594 while (++index < size) {
2595 value = array[index];
2596 iterator(value, createCallback(value));
2597 }
2598 }
2599 }
2600
2601 /**
2602 * @private
2603 */
2604 function baseEachValue(object, iterator, createCallback, keys) {
2605 var key, value;
2606 var index = -1;
2607 var size = keys.length;
2608
2609 if (iterator.length === 3) {
2610 while (++index < size) {
2611 key = keys[index];
2612 value = object[key];
2613 iterator(value, key, createCallback(value));
2614 }
2615 } else {
2616 while (++index < size) {
2617 value = object[keys[index]];
2618 iterator(value, createCallback(value));
2619 }
2620 }
2621 }
2622
2623 /**
2624 * @private
2625 */
2626 function symbolEachValue(collection, iterator, createCallback) {
2627 var value, item;
2628 var index = -1;
2629 var iter = collection[iteratorSymbol]();
2630
2631 if (iterator.length === 3) {
2632 while ((item = iter.next()).done === false) {
2633 value = item.value;
2634 iterator(value, ++index, createCallback(value));
2635 }
2636 } else {
2637 while ((item = iter.next()).done === false) {
2638 value = item.value;
2639 iterator(value, createCallback(value));
2640 }
2641 }
2642 }
2643
2644 /**
2645 * @private
2646 */
2647 function arrayEachIndexValue(array, iterator, createCallback) {
2648 var value;
2649 var index = -1;
2650 var size = array.length;
2651
2652 if (iterator.length === 3) {
2653 while (++index < size) {
2654 value = array[index];
2655 iterator(value, index, createCallback(index, value));
2656 }
2657 } else {
2658 while (++index < size) {
2659 value = array[index];
2660 iterator(value, createCallback(index, value));
2661 }
2662 }
2663 }
2664
2665 /**
2666 * @private
2667 */
2668 function baseEachIndexValue(object, iterator, createCallback, keys) {
2669 var key, value;
2670 var index = -1;
2671 var size = keys.length;
2672
2673 if (iterator.length === 3) {
2674 while (++index < size) {
2675 key = keys[index];
2676 value = object[key];
2677 iterator(value, key, createCallback(index, value));
2678 }
2679 } else {
2680 while (++index < size) {
2681 value = object[keys[index]];
2682 iterator(value, createCallback(index, value));
2683 }
2684 }
2685 }
2686
2687 /**
2688 * @private
2689 */
2690 function symbolEachIndexValue(collection, iterator, createCallback) {
2691 var value, item;
2692 var index = -1;
2693 var iter = collection[iteratorSymbol]();
2694
2695 if (iterator.length === 3) {
2696 while ((item = iter.next()).done === false) {
2697 value = item.value;
2698 iterator(value, ++index, createCallback(index, value));
2699 }
2700 } else {
2701 while ((item = iter.next()).done === false) {
2702 value = item.value;
2703 iterator(value, createCallback(++index, value));
2704 }
2705 }
2706 }
2707
2708 /**
2709 * @private
2710 */
2711 function baseEachKeyValue(object, iterator, createCallback, keys) {
2712 var key, value;
2713 var index = -1;
2714 var size = keys.length;
2715
2716 if (iterator.length === 3) {
2717 while (++index < size) {
2718 key = keys[index];
2719 value = object[key];
2720 iterator(value, key, createCallback(key, value));
2721 }
2722 } else {
2723 while (++index < size) {
2724 key = keys[index];
2725 value = object[key];
2726 iterator(value, createCallback(key, value));
2727 }
2728 }
2729 }
2730
2731 /**
2732 * @private
2733 */
2734 function symbolEachKeyValue(collection, iterator, createCallback) {
2735 var value, item;
2736 var index = -1;
2737 var iter = collection[iteratorSymbol]();
2738
2739 if (iterator.length === 3) {
2740 while ((item = iter.next()).done === false) {
2741 value = item.value;
2742 iterator(value, ++index, createCallback(index, value));
2743 }
2744 } else {
2745 while ((item = iter.next()).done === false) {
2746 value = item.value;
2747 iterator(value, createCallback(++index, value));
2748 }
2749 }
2750 }
2751
2752 /**
2753 * @private
2754 * @param {Function} func
2755 */
2756 function onlyOnce(func) {
2757 return function(err, res) {
2758 var fn = func;
2759 func = throwError;
2760 fn(err, res);
2761 };
2762 }
2763
2764 /**
2765 * @private
2766 * @param {Function} func
2767 */
2768 function once(func) {
2769 return function(err, res) {
2770 var fn = func;
2771 func = noop;
2772 fn(err, res);
2773 };
2774 }
2775
2776
2777 /**
2778 * @private
2779 * @param {Function} arrayEach
2780 * @param {Function} baseEach
2781 */
2782 function createEach(arrayEach, baseEach, symbolEach) {
2783
2784 return function each(collection, iterator, callback) {
2785 callback = callback || noop;
2786 var size, keys;
2787 var completed = 0;
2788 if (isArray(collection)) {
2789 size = collection.length;
2790 arrayEach(collection, iterator, done);
2791 } else if (!collection) {
2792 } else if (iteratorSymbol && collection[iteratorSymbol]) {
2793 size = collection.size;
2794 symbolEach(collection, iterator, done);
2795 } else if (typeof collection === obj) {
2796 keys = nativeKeys(collection);
2797 size = keys.length;
2798 baseEach(collection, iterator, done, keys);
2799 }
2800 if (!size) {
2801 callback(null);
2802 }
2803
2804 function done(err, bool) {
2805 if (err) {
2806 callback = once(callback);
2807 callback(err);
2808 } else if (++completed === size) {
2809 callback(null);
2810 } else if (bool === false) {
2811 callback = once(callback);
2812 callback(null);
2813 }
2814 }
2815 };
2816 }
2817
2818 /**
2819 * @private
2820 * @param {Function} arrayEach
2821 * @param {Function} baseEach
2822 * @param {Function} symbolEach
2823 */
2824 function createMap(arrayEach, baseEach, symbolEach, useArray) {
2825
2826 var init, clone;
2827 if (useArray) {
2828 init = Array;
2829 clone = createArray;
2830 } else {
2831 init = function() {
2832 return {};
2833 };
2834 clone = objectClone;
2835 }
2836
2837 return function(collection, iterator, callback) {
2838 callback = callback || noop;
2839 var size, keys, result;
2840 var completed = 0;
2841
2842 if (isArray(collection)) {
2843 size = collection.length;
2844 result = init(size);
2845 arrayEach(collection, iterator, createCallback);
2846 } else if (!collection) {
2847 } else if (iteratorSymbol && collection[iteratorSymbol]) {
2848 size = collection.size;
2849 result = init(size);
2850 symbolEach(collection, iterator, createCallback);
2851 } else if (typeof collection === obj) {
2852 keys = nativeKeys(collection);
2853 size = keys.length;
2854 result = init(size);
2855 baseEach(collection, iterator, createCallback, keys);
2856 }
2857 if (!size) {
2858 callback(null, init());
2859 }
2860
2861 function createCallback(key) {
2862 return function done(err, res) {
2863 if (key === null) {
2864 throwError();
2865 }
2866 if (err) {
2867 key = null;
2868 callback = once(callback);
2869 callback(err, clone(result));
2870 return;
2871 }
2872 result[key] = res;
2873 key = null;
2874 if (++completed === size) {
2875 callback(null, result);
2876 }
2877 };
2878 }
2879 };
2880 }
2881
2882 /**
2883 * @private
2884 * @param {Function} arrayEach
2885 * @param {Function} baseEach
2886 * @param {Function} symbolEach
2887 * @param {boolean} bool
2888 */
2889 function createFilter(arrayEach, baseEach, symbolEach, bool) {
2890
2891 return function(collection, iterator, callback) {
2892 callback = callback || noop;
2893 var size, keys, result;
2894 var completed = 0;
2895
2896 if (isArray(collection)) {
2897 size = collection.length;
2898 result = Array(size);
2899 arrayEach(collection, iterator, createCallback);
2900 } else if (!collection) {
2901 } else if (iteratorSymbol && collection[iteratorSymbol]) {
2902 size = collection.size;
2903 result = Array(size);
2904 symbolEach(collection, iterator, createCallback);
2905 } else if (typeof collection === obj) {
2906 keys = nativeKeys(collection);
2907 size = keys.length;
2908 result = Array(size);
2909 baseEach(collection, iterator, createCallback, keys);
2910 }
2911 if (!size) {
2912 return callback(null, []);
2913 }
2914
2915 function createCallback(index, value) {
2916 return function done(err, res) {
2917 if (index === null) {
2918 throwError();
2919 }
2920 if (err) {
2921 index = null;
2922 callback = once(callback);
2923 callback(err);
2924 return;
2925 }
2926 if (!!res === bool) {
2927 result[index] = value;
2928 }
2929 index = null;
2930 if (++completed === size) {
2931 callback(null, compact(result));
2932 }
2933 };
2934 }
2935 };
2936 }
2937
2938 /**
2939 * @private
2940 * @param {boolean} bool
2941 */
2942 function createFilterSeries(bool) {
2943
2944 return function(collection, iterator, callback) {
2945 callback = onlyOnce(callback || noop);
2946 var size, key, value, keys, iter, iterate;
2947 var sync = false;
2948 var completed = 0;
2949 var result = [];
2950
2951 if (isArray(collection)) {
2952 size = collection.length;
2953 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
2954 } else if (!collection) {
2955 } else if (iteratorSymbol && collection[iteratorSymbol]) {
2956 size = collection.size;
2957 iter = collection[iteratorSymbol]();
2958 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
2959 } else if (typeof collection === obj) {
2960 keys = nativeKeys(collection);
2961 size = keys.length;
2962 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
2963 }
2964 if (!size) {
2965 return callback(null, []);
2966 }
2967 iterate();
2968
2969 function arrayIterator() {
2970 value = collection[completed];
2971 iterator(value, done);
2972 }
2973
2974 function arrayIteratorWithIndex() {
2975 value = collection[completed];
2976 iterator(value, completed, done);
2977 }
2978
2979 function symbolIterator() {
2980 value = iter.next().value;
2981 iterator(value, done);
2982 }
2983
2984 function symbolIteratorWithKey() {
2985 value = iter.next().value;
2986 iterator(value, completed, done);
2987 }
2988
2989 function objectIterator() {
2990 key = keys[completed];
2991 value = collection[key];
2992 iterator(value, done);
2993 }
2994
2995 function objectIteratorWithKey() {
2996 key = keys[completed];
2997 value = collection[key];
2998 iterator(value, key, done);
2999 }
3000
3001 function done(err, res) {
3002 if (err) {
3003 callback(err);
3004 return;
3005 }
3006 if (!!res === bool) {
3007 result[result.length] = value;
3008 }
3009 if (++completed === size) {
3010 iterate = throwError;
3011 callback(null, result);
3012 } else if (sync) {
3013 nextTick(iterate);
3014 } else {
3015 sync = true;
3016 iterate();
3017 }
3018 sync = false;
3019 }
3020 };
3021 }
3022
3023 /**
3024 * @private
3025 * @param {boolean} bool
3026 */
3027 function createFilterLimit(bool) {
3028
3029 return function(collection, limit, iterator, callback) {
3030 callback = callback || noop;
3031 var size, index, key, value, keys, iter, item, iterate, result;
3032 var sync = false;
3033 var started = 0;
3034 var completed = 0;
3035
3036 if (isArray(collection)) {
3037 size = collection.length;
3038 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3039 } else if (!collection) {
3040 } else if (iteratorSymbol && collection[iteratorSymbol]) {
3041 size = collection.size;
3042 iter = collection[iteratorSymbol]();
3043 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3044 } else if (typeof collection === obj) {
3045 keys = nativeKeys(collection);
3046 size = keys.length;
3047 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3048 }
3049 if (!size || isNaN(limit) || limit < 1) {
3050 return callback(null, []);
3051 }
3052 result = Array(size);
3053 timesSync(limit > size ? size : limit, iterate);
3054
3055 function arrayIterator() {
3056 index = started++;
3057 if (index < size) {
3058 value = collection[index];
3059 iterator(value, createCallback(value, index));
3060 }
3061 }
3062
3063 function arrayIteratorWithIndex() {
3064 index = started++;
3065 if (index < size) {
3066 value = collection[index];
3067 iterator(value, index, createCallback(value, index));
3068 }
3069 }
3070
3071 function symbolIterator() {
3072 if ((item = iter.next()).done === false) {
3073 value = item.value;
3074 iterator(value, createCallback(value, started++));
3075 }
3076 }
3077
3078 function symbolIteratorWithKey() {
3079 if ((item = iter.next()).done === false) {
3080 value = item.value;
3081 iterator(value, started, createCallback(value, started++));
3082 }
3083 }
3084
3085 function objectIterator() {
3086 index = started++;
3087 if (index < size) {
3088 value = collection[keys[index]];
3089 iterator(value, createCallback(value, index));
3090 }
3091 }
3092
3093 function objectIteratorWithKey() {
3094 index = started++;
3095 if (index < size) {
3096 key = keys[index];
3097 value = collection[key];
3098 iterator(value, key, createCallback(value, index));
3099 }
3100 }
3101
3102 function createCallback(value, index) {
3103 return function(err, res) {
3104 if (index === null) {
3105 throwError();
3106 }
3107 if (err) {
3108 index = null;
3109 iterate = noop;
3110 callback = once(callback);
3111 callback(err);
3112 return;
3113 }
3114 if (!!res === bool) {
3115 result[index] = value;
3116 }
3117 index = null;
3118 if (++completed === size) {
3119 callback = onlyOnce(callback);
3120 callback(null, compact(result));
3121 } else if (sync) {
3122 nextTick(iterate);
3123 } else {
3124 sync = true;
3125 iterate();
3126 }
3127 sync = false;
3128 };
3129 }
3130 };
3131 }
3132
3133 /**
3134 * @memberof async
3135 * @namespace eachSeries
3136 * @param {Array|Object} collection
3137 * @param {Function} iterator
3138 * @param {Function} callback
3139 * @example
3140 *
3141 * // array
3142 * var order = [];
3143 * var array = [1, 3, 2];
3144 * var iterator = function(num, done) {
3145 * setTimeout(function() {
3146 * order.push(num);
3147 * done();
3148 * }, num * 10);
3149 * };
3150 * async.eachSeries(array, iterator, function(err, res) {
3151 * console.log(res); // undefined
3152 * console.log(order); // [1, 3, 2]
3153 * });
3154 *
3155 * @example
3156 *
3157 * // array with index
3158 * var order = [];
3159 * var array = [1, 3, 2];
3160 * var iterator = function(num, index, done) {
3161 * setTimeout(function() {
3162 * order.push([num, index]);
3163 * done();
3164 * }, num * 10);
3165 * };
3166 * async.eachSeries(array, iterator, function(err, res) {
3167 * console.log(res); // undefined
3168 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
3169 * });
3170 *
3171 * @example
3172 *
3173 * // object
3174 * var order = [];
3175 * var object = { a: 1, b: 3, c: 2 };
3176 * var iterator = function(num, done) {
3177 * setTimeout(function() {
3178 * order.push(num);
3179 * done();
3180 * }, num * 10);
3181 * };
3182 * async.eachSeries(object, iterator, function(err, res) {
3183 * console.log(res); // undefined
3184 * console.log(order); // [1, 3, 2]
3185 * });
3186 *
3187 * @example
3188 *
3189 * // object with key
3190 * var order = [];
3191 * var object = { a: 1, b: 3, c: 2 };
3192 * var iterator = function(num, key, done) {
3193 * setTimeout(function() {
3194 * order.push([num, key]);
3195 * done();
3196 * }, num * 10);
3197 * };
3198 * async.eachSeries(object, iterator, function(err, res) {
3199 * console.log(res); // undefined
3200 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b']]
3201 * });
3202 *
3203 * @example
3204 *
3205 * // break
3206 * var order = [];
3207 * var array = [1, 3, 2];
3208 * var iterator = function(num, done) {
3209 * setTimeout(function() {
3210 * order.push(num);
3211 * done(null, num !== 3);
3212 * }, num * 10);
3213 * };
3214 * async.eachSeries(array, iterator, function(err, res) {
3215 * console.log(res); // undefined
3216 * console.log(order); // [1, 3]
3217 * });
3218 */
3219 function eachSeries(collection, iterator, callback) {
3220 callback = onlyOnce(callback || noop);
3221 var size, key, keys, iter, value, iterate;
3222 var sync = false;
3223 var completed = 0;
3224
3225 if (isArray(collection)) {
3226 size = collection.length;
3227 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3228 } else if (!collection) {
3229 } else if (iteratorSymbol && collection[iteratorSymbol]) {
3230 size = collection.size;
3231 iter = collection[iteratorSymbol]();
3232 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3233 } else if (typeof collection === obj) {
3234 keys = nativeKeys(collection);
3235 size = keys.length;
3236 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3237 }
3238 if (!size) {
3239 return callback(null);
3240 }
3241 iterate();
3242
3243 function arrayIterator() {
3244 iterator(collection[completed], done);
3245 }
3246
3247 function arrayIteratorWithIndex() {
3248 iterator(collection[completed], completed, done);
3249 }
3250
3251 function symbolIterator() {
3252 iterator(iter.next().value, done);
3253 }
3254
3255 function symbolIteratorWithKey() {
3256 value = iter.next().value;
3257 iterator(value, completed, done);
3258 }
3259
3260 function objectIterator() {
3261 iterator(collection[keys[completed]], done);
3262 }
3263
3264 function objectIteratorWithKey() {
3265 key = keys[completed];
3266 iterator(collection[key], key, done);
3267 }
3268
3269 function done(err, bool) {
3270 if (err) {
3271 callback(err);
3272 } else if (++completed === size) {
3273 iterate = throwError;
3274 callback(null);
3275 } else if (bool === false) {
3276 iterate = throwError;
3277 callback(null);
3278 } else if (sync) {
3279 nextTick(iterate);
3280 } else {
3281 sync = true;
3282 iterate();
3283 }
3284 sync = false;
3285 }
3286 }
3287
3288 /**
3289 * @memberof async
3290 * @namespace eachLimit
3291 * @param {Array|Object} collection
3292 * @param {number} limit - limit >= 1
3293 * @param {Function} iterator
3294 * @param {Function} callback
3295 * @example
3296 *
3297 * // array
3298 * var order = [];
3299 * var array = [1, 5, 3, 4, 2];
3300 * var iterator = function(num, done) {
3301 * setTimeout(function() {
3302 * order.push(num);
3303 * done();
3304 * }, num * 10);
3305 * };
3306 * async.eachLimit(array, 2, iterator, function(err, res) {
3307 * console.log(res); // undefined
3308 * console.log(order); // [1, 3, 5, 2, 4]
3309 * });
3310 *
3311 * @example
3312 *
3313 * // array with index
3314 * var order = [];
3315 * var array = [1, 5, 3, 4, 2];
3316 * var iterator = function(num, index, done) {
3317 * setTimeout(function() {
3318 * order.push([num, index]);
3319 * done();
3320 * }, num * 10);
3321 * };
3322 * async.eachLimit(array, 2, iterator, function(err, res) {
3323 * console.log(res); // undefined
3324 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
3325 * });
3326 *
3327 * @example
3328 *
3329 * // object
3330 * var order = [];
3331 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3332 * var iterator = function(num, done) {
3333 * setTimeout(function() {
3334 * order.push(num);
3335 * done();
3336 * }, num * 10);
3337 * };
3338 * async.eachLimit(object, 2, iterator, function(err, res) {
3339 * console.log(res); // undefined
3340 * console.log(order); // [1, 3, 5, 2, 4]
3341 * });
3342 *
3343 * @example
3344 *
3345 * // object with key
3346 * var order = [];
3347 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3348 * var iterator = function(num, key, done) {
3349 * setTimeout(function() {
3350 * order.push([num, key]);
3351 * done();
3352 * }, num * 10);
3353 * };
3354 * async.eachLimit(object, 2, iterator, function(err, res) {
3355 * console.log(res); // undefined
3356 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
3357 * });
3358 *
3359 * @example
3360 *
3361 * // break
3362 * var order = [];
3363 * var array = [1, 5, 3, 4, 2];
3364 * var iterator = function(num, done) {
3365 * setTimeout(function() {
3366 * order.push(num);
3367 * done(null, num !== 5);
3368 * }, num * 10);
3369 * };
3370 * async.eachLimit(array, 2, iterator, function(err, res) {
3371 * console.log(res); // undefined
3372 * console.log(order); // [1, 3, 5]
3373 * });
3374 *
3375 */
3376 function eachLimit(collection, limit, iterator, callback) {
3377 callback = callback || noop;
3378 var size, index, key, keys, iter, item, iterate;
3379 var sync = false;
3380 var started = 0;
3381 var completed = 0;
3382
3383 if (isArray(collection)) {
3384 size = collection.length;
3385 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3386 } else if (!collection) {
3387 } else if (iteratorSymbol && collection[iteratorSymbol]) {
3388 size = collection.size;
3389 iter = collection[iteratorSymbol]();
3390 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3391 } else if (typeof collection === obj) {
3392 keys = nativeKeys(collection);
3393 size = keys.length;
3394 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3395 } else {
3396 return callback(null);
3397 }
3398 if (!size || isNaN(limit) || limit < 1) {
3399 return callback(null);
3400 }
3401 timesSync(limit > size ? size : limit, iterate);
3402
3403 function arrayIterator() {
3404 if (started < size) {
3405 iterator(collection[started++], done);
3406 }
3407 }
3408
3409 function arrayIteratorWithIndex() {
3410 index = started++;
3411 if (index < size) {
3412 iterator(collection[index], index, done);
3413 }
3414 }
3415
3416 function symbolIterator() {
3417 if ((item = iter.next()).done === false) {
3418 iterator(item.value, done);
3419 }
3420 }
3421
3422 function symbolIteratorWithKey() {
3423 if ((item = iter.next()).done === false) {
3424 iterator(item.value, started++, done);
3425 }
3426 }
3427
3428 function objectIterator() {
3429 if (started < size) {
3430 iterator(collection[keys[started++]], done);
3431 }
3432 }
3433
3434 function objectIteratorWithKey() {
3435 index = started++;
3436 if (index < size) {
3437 key = keys[index];
3438 iterator(collection[key], key, done);
3439 }
3440 }
3441
3442 function done(err, bool) {
3443 if (err) {
3444 iterate = noop;
3445 callback = once(callback);
3446 callback(err);
3447 } else if (++completed === size) {
3448 iterate = throwError;
3449 callback = onlyOnce(callback);
3450 callback(null);
3451 } else if (bool === false) {
3452 iterate = noop;
3453 callback = once(callback);
3454 callback(null);
3455 } else if (sync) {
3456 nextTick(iterate);
3457 } else {
3458 sync = true;
3459 iterate();
3460 }
3461 sync = false;
3462 }
3463 }
3464
3465 /**
3466 * @memberof async
3467 * @namespace mapSeries
3468 * @param {Array|Object} collection
3469 * @param {Function} iterator
3470 * @param {Function} callback
3471 * @example
3472 *
3473 * // array
3474 * var order = [];
3475 * var array = [1, 3, 2];
3476 * var iterator = function(num, done) {
3477 * setTimeout(function() {
3478 * order.push(num);
3479 * done(null, num);
3480 * }, num * 10);
3481 * };
3482 * async.mapSeries(array, iterator, function(err, res) {
3483 * console.log(res); // [1, 3, 2];
3484 * console.log(order); // [1, 3, 2]
3485 * });
3486 *
3487 * @example
3488 *
3489 * // array with index
3490 * var order = [];
3491 * var array = [1, 3, 2];
3492 * var iterator = function(num, index, done) {
3493 * setTimeout(function() {
3494 * order.push([num, index]);
3495 * done(null, num);
3496 * }, num * 10);
3497 * };
3498 * async.mapSeries(array, iterator, function(err, res) {
3499 * console.log(res); // [1, 3, 2]
3500 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
3501 * });
3502 *
3503 * @example
3504 *
3505 * // object
3506 * var order = [];
3507 * var object = { a: 1, b: 3, c: 2 };
3508 * var iterator = function(num, done) {
3509 * setTimeout(function() {
3510 * order.push(num);
3511 * done(null, num);
3512 * }, num * 10);
3513 * };
3514 * async.mapSeries(object, iterator, function(err, res) {
3515 * console.log(res); // [1, 3, 2]
3516 * console.log(order); // [1, 3, 2]
3517 * });
3518 *
3519 * @example
3520 *
3521 * // object with key
3522 * var order = [];
3523 * var object = { a: 1, b: 3, c: 2 };
3524 * var iterator = function(num, key, done) {
3525 * setTimeout(function() {
3526 * order.push([num, key]);
3527 * done(null, num);
3528 * }, num * 10);
3529 * };
3530 * async.mapSeries(object, iterator, function(err, res) {
3531 * console.log(res); // [1, 3, 2]
3532 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
3533 * });
3534 *
3535 */
3536 function mapSeries(collection, iterator, callback) {
3537 callback = callback || noop;
3538 var size, key, keys, iter, value, result, iterate;
3539 var sync = false;
3540 var completed = 0;
3541
3542 if (isArray(collection)) {
3543 size = collection.length;
3544 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3545 } else if (!collection) {
3546 } else if (iteratorSymbol && collection[iteratorSymbol]) {
3547 size = collection.size;
3548 iter = collection[iteratorSymbol]();
3549 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3550 } else if (typeof collection === obj) {
3551 keys = nativeKeys(collection);
3552 size = keys.length;
3553 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3554 }
3555 if (!size) {
3556 return callback(null, []);
3557 }
3558 result = Array(size);
3559 iterate();
3560
3561 function arrayIterator() {
3562 iterator(collection[completed], done);
3563 }
3564
3565 function arrayIteratorWithIndex() {
3566 iterator(collection[completed], completed, done);
3567 }
3568
3569 function symbolIterator() {
3570 iterator(iter.next().value, done);
3571 }
3572
3573 function symbolIteratorWithKey() {
3574 value = iter.next().value;
3575 iterator(value, completed, done);
3576 }
3577
3578 function objectIterator() {
3579 iterator(collection[keys[completed]], done);
3580 }
3581
3582 function objectIteratorWithKey() {
3583 key = keys[completed];
3584 iterator(collection[key], key, done);
3585 }
3586
3587 function done(err, res) {
3588 if (err) {
3589 iterate = throwError;
3590 callback = onlyOnce(callback);
3591 callback(err, createArray(result));
3592 return;
3593 }
3594 result[completed] = res;
3595 if (++completed === size) {
3596 iterate = throwError;
3597 callback(null, result);
3598 callback = throwError;
3599 } else if (sync) {
3600 nextTick(iterate);
3601 } else {
3602 sync = true;
3603 iterate();
3604 }
3605 sync = false;
3606 }
3607 }
3608
3609 /**
3610 * @memberof async
3611 * @namespace mapLimit
3612 * @param {Array|Object} collection
3613 * @param {number} limit - limit >= 1
3614 * @param {Function} iterator
3615 * @param {Function} callback
3616 * @example
3617 *
3618 * // array
3619 * var order = [];
3620 * var array = [1, 5, 3, 4, 2];
3621 * var iterator = function(num, done) {
3622 * setTimeout(function() {
3623 * order.push(num);
3624 * done(null, num);
3625 * }, num * 10);
3626 * };
3627 * async.mapLimit(array, 2, iterator, function(err, res) {
3628 * console.log(res); // [1, 5, 3, 4, 2]
3629 * console.log(order); // [1, 3, 5, 2, 4]
3630 * });
3631 *
3632 * @example
3633 *
3634 * // array with index
3635 * var order = [];
3636 * var array = [1, 5, 3, 4, 2];
3637 * var iterator = function(num, index, done) {
3638 * setTimeout(function() {
3639 * order.push([num, index]);
3640 * done(null, num);
3641 * }, num * 10);
3642 * };
3643 * async.mapLimit(array, 2, iterator, function(err, res) {
3644 * console.log(res); // [1, 5, 3, 4, 2]
3645 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
3646 * });
3647 *
3648 * @example
3649 *
3650 * // object
3651 * var order = [];
3652 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3653 * var iterator = function(num, done) {
3654 * setTimeout(function() {
3655 * order.push(num);
3656 * done(null, num);
3657 * }, num * 10);
3658 * };
3659 * async.mapLimit(object, 2, iterator, function(err, res) {
3660 * console.log(res); // [1, 5, 3, 4, 2]
3661 * console.log(order); // [1, 3, 5, 2, 4]
3662 * });
3663 *
3664 * @example
3665 *
3666 * // object with key
3667 * var order = [];
3668 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3669 * var iterator = function(num, key, done) {
3670 * setTimeout(function() {
3671 * order.push([num, key]);
3672 * done(null, num);
3673 * }, num * 10);
3674 * };
3675 * async.mapLimit(object, 2, iterator, function(err, res) {
3676 * console.log(res); // [1, 5, 3, 4, 2]
3677 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
3678 * });
3679 *
3680 */
3681 function mapLimit(collection, limit, iterator, callback) {
3682 callback = callback || noop;
3683 var size, index, key, keys, iter, item, result, iterate;
3684 var sync = false;
3685 var started = 0;
3686 var completed = 0;
3687
3688 if (isArray(collection)) {
3689 size = collection.length;
3690 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3691 } else if (!collection) {
3692 } else if (iteratorSymbol && collection[iteratorSymbol]) {
3693 size = collection.size;
3694 iter = collection[iteratorSymbol]();
3695 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3696 } else if (typeof collection === obj) {
3697 keys = nativeKeys(collection);
3698 size = keys.length;
3699 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3700 }
3701 if (!size || isNaN(limit) || limit < 1) {
3702 return callback(null, []);
3703 }
3704 result = Array(size);
3705 timesSync(limit > size ? size : limit, iterate);
3706
3707 function arrayIterator() {
3708 index = started++;
3709 if (index < size) {
3710 iterator(collection[index], createCallback(index));
3711 }
3712 }
3713
3714 function arrayIteratorWithIndex() {
3715 index = started++;
3716 if (index < size) {
3717 iterator(collection[index], index, createCallback(index));
3718 }
3719 }
3720
3721 function symbolIterator() {
3722 if ((item = iter.next()).done === false) {
3723 iterator(item.value, createCallback(started++));
3724 }
3725 }
3726
3727 function symbolIteratorWithKey() {
3728 if ((item = iter.next()).done === false) {
3729 iterator(item.value, started, createCallback(started++));
3730 }
3731 }
3732
3733 function objectIterator() {
3734 index = started++;
3735 if (index < size) {
3736 iterator(collection[keys[index]], createCallback(index));
3737 }
3738 }
3739
3740 function objectIteratorWithKey() {
3741 index = started++;
3742 if (index < size) {
3743 key = keys[index];
3744 iterator(collection[key], key, createCallback(index));
3745 }
3746 }
3747
3748 function createCallback(index) {
3749 return function(err, res) {
3750 if (index === null) {
3751 throwError();
3752 }
3753 if (err) {
3754 index = null;
3755 iterate = noop;
3756 callback = once(callback);
3757 callback(err, createArray(result));
3758 return;
3759 }
3760 result[index] = res;
3761 index = null;
3762 if (++completed === size) {
3763 iterate = throwError;
3764 callback(null, result);
3765 callback = throwError;
3766 } else if (sync) {
3767 nextTick(iterate);
3768 } else {
3769 sync = true;
3770 iterate();
3771 }
3772 sync = false;
3773 };
3774 }
3775 }
3776
3777 /**
3778 * @memberof async
3779 * @namespace mapValuesSeries
3780 * @param {Array|Object} collection
3781 * @param {Function} iterator
3782 * @param {Function} callback
3783 * @example
3784 *
3785 * // array
3786 * var order = [];
3787 * var array = [1, 3, 2];
3788 * var iterator = function(num, done) {
3789 * setTimeout(function() {
3790 * order.push(num);
3791 * done(null, num);
3792 * }, num * 10);
3793 * };
3794 * async.mapValuesSeries(array, iterator, function(err, res) {
3795 * console.log(res); // { '0': 1, '1': 3, '2': 2 }
3796 * console.log(order); // [1, 3, 2]
3797 * });
3798 *
3799 * @example
3800 *
3801 * // array with index
3802 * var order = [];
3803 * var array = [1, 3, 2];
3804 * var iterator = function(num, index, done) {
3805 * setTimeout(function() {
3806 * order.push([num, index]);
3807 * done(null, num);
3808 * }, num * 10);
3809 * };
3810 * async.mapValuesSeries(array, iterator, function(err, res) {
3811 * console.log(res); // { '0': 1, '1': 3, '2': 2 }
3812 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
3813 * });
3814 *
3815 * @example
3816 *
3817 * // object
3818 * var order = [];
3819 * var object = { a: 1, b: 3, c: 2 };
3820 * var iterator = function(num, done) {
3821 * setTimeout(function() {
3822 * order.push(num);
3823 * done(null, num);
3824 * }, num * 10);
3825 * };
3826 * async.mapValuesSeries(object, iterator, function(err, res) {
3827 * console.log(res); // { a: 1, b: 3, c: 2 }
3828 * console.log(order); // [1, 3, 2]
3829 * });
3830 *
3831 * @example
3832 *
3833 * // object with key
3834 * var order = [];
3835 * var object = { a: 1, b: 3, c: 2 };
3836 * var iterator = function(num, key, done) {
3837 * setTimeout(function() {
3838 * order.push([num, key]);
3839 * done(null, num);
3840 * }, num * 10);
3841 * };
3842 * async.mapValuesSeries(object, iterator, function(err, res) {
3843 * console.log(res); // { a: 1, b: 3, c: 2 }
3844 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
3845 * });
3846 *
3847 */
3848 function mapValuesSeries(collection, iterator, callback) {
3849 callback = callback || noop;
3850 var size, key, keys, iter, value, iterate;
3851 var sync = false;
3852 var result = {};
3853 var completed = 0;
3854
3855 if (isArray(collection)) {
3856 size = collection.length;
3857 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
3858 } else if (!collection) {
3859 } else if (iteratorSymbol && collection[iteratorSymbol]) {
3860 size = collection.size;
3861 iter = collection[iteratorSymbol]();
3862 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
3863 } else if (typeof collection === obj) {
3864 keys = nativeKeys(collection);
3865 size = keys.length;
3866 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
3867 }
3868 if (!size) {
3869 return callback(null, result);
3870 }
3871 iterate();
3872
3873 function arrayIterator() {
3874 key = completed;
3875 iterator(collection[completed], done);
3876 }
3877
3878 function arrayIteratorWithIndex() {
3879 key = completed;
3880 iterator(collection[completed], completed, done);
3881 }
3882
3883 function symbolIterator() {
3884 key = completed;
3885 value = iter.next().value;
3886 iterator(value, done);
3887 }
3888
3889 function symbolIteratorWithKey() {
3890 key = completed;
3891 value = iter.next().value;
3892 iterator(value, completed, done);
3893 }
3894
3895 function objectIterator() {
3896 key = keys[completed];
3897 iterator(collection[key], done);
3898 }
3899
3900 function objectIteratorWithKey() {
3901 key = keys[completed];
3902 iterator(collection[key], key, done);
3903 }
3904
3905 function done(err, res) {
3906 if (err) {
3907 iterate = throwError;
3908 callback = onlyOnce(callback);
3909 callback(err, objectClone(result));
3910 return;
3911 }
3912 result[key] = res;
3913 if (++completed === size) {
3914 iterate = throwError;
3915 callback(null, result);
3916 callback = throwError;
3917 } else if (sync) {
3918 nextTick(iterate);
3919 } else {
3920 sync = true;
3921 iterate();
3922 }
3923 sync = false;
3924 }
3925 }
3926
3927 /**
3928 * @memberof async
3929 * @namespace mapValuesLimit
3930 * @param {Array|Object} collection
3931 * @param {number} limit - limit >= 1
3932 * @param {Function} iterator
3933 * @param {Function} callback
3934 * @example
3935 *
3936 * // array
3937 * var order = [];
3938 * var array = [1, 5, 3, 4, 2];
3939 * var iterator = function(num, done) {
3940 * setTimeout(function() {
3941 * order.push(num);
3942 * done(null, num);
3943 * }, num * 10);
3944 * };
3945 * async.mapValuesLimit(array, 2, iterator, function(err, res) {
3946 * console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
3947 * console.log(order); // [1, 3, 5, 2, 4]
3948 * });
3949 *
3950 * @example
3951 *
3952 * // array with index
3953 * var order = [];
3954 * var array = [1, 5, 3, 4, 2];
3955 * var iterator = function(num, index, done) {
3956 * setTimeout(function() {
3957 * order.push([num, index]);
3958 * done(null, num);
3959 * }, num * 10);
3960 * };
3961 * async.mapValuesLimit(array, 2, iterator, function(err, res) {
3962 * console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
3963 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
3964 * });
3965 *
3966 * @example
3967 *
3968 * // object
3969 * var order = [];
3970 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3971 * var iterator = function(num, done) {
3972 * setTimeout(function() {
3973 * order.push(num);
3974 * done(null, num);
3975 * }, num * 10);
3976 * };
3977 * async.mapValuesLimit(object, 2, iterator, function(err, res) {
3978 * console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }
3979 * console.log(order); // [1, 3, 5, 2, 4]
3980 * });
3981 *
3982 * @example
3983 *
3984 * // object with key
3985 * var order = [];
3986 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
3987 * var iterator = function(num, key, done) {
3988 * setTimeout(function() {
3989 * order.push([num, key]);
3990 * done(null, num);
3991 * }, num * 10);
3992 * };
3993 * async.mapValuesLimit(object, 2, iterator, function(err, res) {
3994 * console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }
3995 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
3996 * });
3997 *
3998 */
3999 function mapValuesLimit(collection, limit, iterator, callback) {
4000 callback = callback || noop;
4001 var size, index, key, keys, iter, item, iterate;
4002 var sync = false;
4003 var result = {};
4004 var started = 0;
4005 var completed = 0;
4006
4007 if (isArray(collection)) {
4008 size = collection.length;
4009 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4010 } else if (!collection) {
4011 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4012 size = collection.size;
4013 iter = collection[iteratorSymbol]();
4014 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4015 } else if (typeof collection === obj) {
4016 keys = nativeKeys(collection);
4017 size = keys.length;
4018 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4019 }
4020 if (!size || isNaN(limit) || limit < 1) {
4021 return callback(null, result);
4022 }
4023 timesSync(limit > size ? size : limit, iterate);
4024
4025 function arrayIterator() {
4026 index = started++;
4027 if (index < size) {
4028 iterator(collection[index], createCallback(index));
4029 }
4030 }
4031
4032 function arrayIteratorWithIndex() {
4033 index = started++;
4034 if (index < size) {
4035 iterator(collection[index], index, createCallback(index));
4036 }
4037 }
4038
4039 function symbolIterator() {
4040 if ((item = iter.next()).done === false) {
4041 iterator(item.value, createCallback(started++));
4042 }
4043 }
4044
4045 function symbolIteratorWithKey() {
4046 if ((item = iter.next()).done === false) {
4047 iterator(item.value, started, createCallback(started++));
4048 }
4049 }
4050
4051 function objectIterator() {
4052 index = started++;
4053 if (index < size) {
4054 key = keys[index];
4055 iterator(collection[key], createCallback(key));
4056 }
4057 }
4058
4059 function objectIteratorWithKey() {
4060 index = started++;
4061 if (index < size) {
4062 key = keys[index];
4063 iterator(collection[key], key, createCallback(key));
4064 }
4065 }
4066
4067 function createCallback(key) {
4068 return function(err, res) {
4069 if (key === null) {
4070 throwError();
4071 }
4072 if (err) {
4073 key = null;
4074 iterate = noop;
4075 callback = once(callback);
4076 callback(err, objectClone(result));
4077 return;
4078 }
4079 result[key] = res;
4080 key = null;
4081 if (++completed === size) {
4082 callback(null, result);
4083 } else if (sync) {
4084 nextTick(iterate);
4085 } else {
4086 sync = true;
4087 iterate();
4088 }
4089 sync = false;
4090 };
4091 }
4092 }
4093
4094 /**
4095 * @private
4096 * @param {Function} arrayEach
4097 * @param {Function} baseEach
4098 * @param {Function} symbolEach
4099 * @param {boolean} bool
4100 */
4101 function createDetect(arrayEach, baseEach, symbolEach, bool) {
4102
4103 return function(collection, iterator, callback) {
4104 callback = callback || noop;
4105 var size, keys;
4106 var completed = 0;
4107
4108 if (isArray(collection)) {
4109 size = collection.length;
4110 arrayEach(collection, iterator, createCallback);
4111 } else if (!collection) {
4112 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4113 size = collection.size;
4114 symbolEach(collection, iterator, createCallback);
4115 } else if (typeof collection === obj) {
4116 keys = nativeKeys(collection);
4117 size = keys.length;
4118 baseEach(collection, iterator, createCallback, keys);
4119 }
4120 if (!size) {
4121 callback(null);
4122 }
4123
4124 function createCallback(value) {
4125 var called = false;
4126 return function done(err, res) {
4127 if (called) {
4128 throwError();
4129 }
4130 called = true;
4131 if (err) {
4132 callback = once(callback);
4133 callback(err);
4134 } else if (!!res === bool) {
4135 callback = once(callback);
4136 callback(null, value);
4137 } else if (++completed === size) {
4138 callback(null);
4139 }
4140 };
4141 }
4142 };
4143 }
4144
4145 /**
4146 * @private
4147 * @param {boolean} bool
4148 */
4149 function createDetectSeries(bool) {
4150
4151 return function(collection, iterator, callback) {
4152 callback = onlyOnce(callback || noop);
4153 var size, key, value, keys, iter, iterate;
4154 var sync = false;
4155 var completed = 0;
4156
4157 if (isArray(collection)) {
4158 size = collection.length;
4159 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4160 } else if (!collection) {
4161 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4162 size = collection.size;
4163 iter = collection[iteratorSymbol]();
4164 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4165 } else if (typeof collection === obj) {
4166 keys = nativeKeys(collection);
4167 size = keys.length;
4168 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4169 }
4170 if (!size) {
4171 return callback(null);
4172 }
4173 iterate();
4174
4175 function arrayIterator() {
4176 value = collection[completed];
4177 iterator(value, done);
4178 }
4179
4180 function arrayIteratorWithIndex() {
4181 value = collection[completed];
4182 iterator(value, completed, done);
4183 }
4184
4185 function symbolIterator() {
4186 value = iter.next().value;
4187 iterator(value, done);
4188 }
4189
4190 function symbolIteratorWithKey() {
4191 value = iter.next().value;
4192 iterator(value, completed, done);
4193 }
4194
4195 function objectIterator() {
4196 value = collection[keys[completed]];
4197 iterator(value, done);
4198 }
4199
4200 function objectIteratorWithKey() {
4201 key = keys[completed];
4202 value = collection[key];
4203 iterator(value, key, done);
4204 }
4205
4206 function done(err, res) {
4207 if (err) {
4208 callback(err);
4209 } else if (!!res === bool) {
4210 iterate = throwError;
4211 callback(null, value);
4212 } else if (++completed === size) {
4213 iterate = throwError;
4214 callback(null);
4215 } else if (sync) {
4216 nextTick(iterate);
4217 } else {
4218 sync = true;
4219 iterate();
4220 }
4221 sync = false;
4222 }
4223 };
4224 }
4225
4226 /**
4227 * @private
4228 * @param {boolean} bool
4229 */
4230 function createDetectLimit(bool) {
4231
4232 return function(collection, limit, iterator, callback) {
4233 callback = callback || noop;
4234 var size, index, key, value, keys, iter, item, iterate;
4235 var sync = false;
4236 var started = 0;
4237 var completed = 0;
4238
4239 if (isArray(collection)) {
4240 size = collection.length;
4241 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4242 } else if (!collection) {
4243 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4244 size = collection.size;
4245 iter = collection[iteratorSymbol]();
4246 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4247 } else if (typeof collection === obj) {
4248 keys = nativeKeys(collection);
4249 size = keys.length;
4250 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4251 }
4252 if (!size || isNaN(limit) || limit < 1) {
4253 return callback(null);
4254 }
4255 timesSync(limit > size ? size : limit, iterate);
4256
4257 function arrayIterator() {
4258 index = started++;
4259 if (index < size) {
4260 value = collection[index];
4261 iterator(value, createCallback(value));
4262 }
4263 }
4264
4265 function arrayIteratorWithIndex() {
4266 index = started++;
4267 if (index < size) {
4268 value = collection[index];
4269 iterator(value, index, createCallback(value));
4270 }
4271 }
4272
4273 function symbolIterator() {
4274 if ((item = iter.next()).done === false) {
4275 value = item.value;
4276 iterator(value, createCallback(value));
4277 }
4278 }
4279
4280 function symbolIteratorWithKey() {
4281 if ((item = iter.next()).done === false) {
4282 value = item.value;
4283 iterator(value, started++, createCallback(value));
4284 }
4285 }
4286
4287 function objectIterator() {
4288 index = started++;
4289 if (index < size) {
4290 value = collection[keys[index]];
4291 iterator(value, createCallback(value));
4292 }
4293 }
4294
4295 function objectIteratorWithKey() {
4296 if (started < size) {
4297 key = keys[started++];
4298 value = collection[key];
4299 iterator(value, key, createCallback(value));
4300 }
4301 }
4302
4303 function createCallback(value) {
4304 var called = false;
4305 return function(err, res) {
4306 if (called) {
4307 throwError();
4308 }
4309 called = true;
4310 if (err) {
4311 iterate = noop;
4312 callback = once(callback);
4313 callback(err);
4314 } else if (!!res === bool) {
4315 iterate = noop;
4316 callback = once(callback);
4317 callback(null, value);
4318 } else if (++completed === size) {
4319 callback(null);
4320 } else if (sync) {
4321 nextTick(iterate);
4322 } else {
4323 sync = true;
4324 iterate();
4325 }
4326 sync = false;
4327 };
4328 }
4329 };
4330 }
4331
4332 /**
4333 * @private
4334 * @param {Function} arrayEach
4335 * @param {Function} baseEach
4336 * @param {Function} symbolEach
4337 * @param {boolean} bool
4338 */
4339 function createPick(arrayEach, baseEach, symbolEach, bool) {
4340
4341 return function(collection, iterator, callback) {
4342 callback = callback || noop;
4343 var size, keys;
4344 var completed = 0;
4345 var result = {};
4346
4347 if (isArray(collection)) {
4348 size = collection.length;
4349 arrayEach(collection, iterator, createCallback);
4350 } else if (!collection) {
4351 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4352 size = collection.size;
4353 symbolEach(collection, iterator, createCallback);
4354 } else if (typeof collection === obj) {
4355 keys = nativeKeys(collection);
4356 size = keys.length;
4357 baseEach(collection, iterator, createCallback, keys);
4358 }
4359 if (!size) {
4360 return callback(null, {});
4361 }
4362
4363 function createCallback(key, value) {
4364 return function done(err, res) {
4365 if (key === null) {
4366 throwError();
4367 }
4368 if (err) {
4369 key = null;
4370 callback = once(callback);
4371 callback(err, objectClone(result));
4372 return;
4373 }
4374 if (!!res === bool) {
4375 result[key] = value;
4376 }
4377 key = null;
4378 if (++completed === size) {
4379 callback(null, result);
4380 }
4381 };
4382 }
4383 };
4384 }
4385
4386 /**
4387 * @private
4388 * @param {boolean} bool
4389 */
4390 function createPickSeries(bool) {
4391
4392 return function(collection, iterator, callback) {
4393 callback = onlyOnce(callback || noop);
4394 var size, key, value, keys, iter, iterate;
4395 var sync = false;
4396 var result = {};
4397 var completed = 0;
4398
4399 if (isArray(collection)) {
4400 size = collection.length;
4401 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4402 } else if (!collection) {
4403 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4404 size = collection.size;
4405 iter = collection[iteratorSymbol]();
4406 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4407 } else if (typeof collection === obj) {
4408 keys = nativeKeys(collection);
4409 size = keys.length;
4410 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4411 }
4412 if (!size) {
4413 return callback(null, {});
4414 }
4415 iterate();
4416
4417 function arrayIterator() {
4418 key = completed;
4419 value = collection[completed];
4420 iterator(value, done);
4421 }
4422
4423 function arrayIteratorWithIndex() {
4424 key = completed;
4425 value = collection[completed];
4426 iterator(value, completed, done);
4427 }
4428
4429 function symbolIterator() {
4430 key = completed;
4431 value = iter.next().value;
4432 iterator(value, done);
4433 }
4434
4435 function symbolIteratorWithKey() {
4436 key = completed;
4437 value = iter.next().value;
4438 iterator(value, key, done);
4439 }
4440
4441 function objectIterator() {
4442 key = keys[completed];
4443 value = collection[key];
4444 iterator(value, done);
4445 }
4446
4447 function objectIteratorWithKey() {
4448 key = keys[completed];
4449 value = collection[key];
4450 iterator(value, key, done);
4451 }
4452
4453 function done(err, res) {
4454 if (err) {
4455 callback(err, result);
4456 return;
4457 }
4458 if (!!res === bool) {
4459 result[key] = value;
4460 }
4461 if (++completed === size) {
4462 iterate = throwError;
4463 callback(null, result);
4464 } else if (sync) {
4465 nextTick(iterate);
4466 } else {
4467 sync = true;
4468 iterate();
4469 }
4470 sync = false;
4471 }
4472 };
4473 }
4474
4475 /**
4476 * @private
4477 * @param {boolean} bool
4478 */
4479 function createPickLimit(bool) {
4480
4481 return function(collection, limit, iterator, callback) {
4482 callback = callback || noop;
4483 var size, index, key, value, keys, iter, item, iterate;
4484 var sync = false;
4485 var result = {};
4486 var started = 0;
4487 var completed = 0;
4488
4489 if (isArray(collection)) {
4490 size = collection.length;
4491 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
4492 } else if (!collection) {
4493 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4494 size = collection.size;
4495 iter = collection[iteratorSymbol]();
4496 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
4497 } else if (typeof collection === obj) {
4498 keys = nativeKeys(collection);
4499 size = keys.length;
4500 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
4501 }
4502 if (!size || isNaN(limit) || limit < 1) {
4503 return callback(null, {});
4504 }
4505 timesSync(limit > size ? size : limit, iterate);
4506
4507 function arrayIterator() {
4508 index = started++;
4509 if (index < size) {
4510 value = collection[index];
4511 iterator(value, createCallback(value, index));
4512 }
4513 }
4514
4515 function arrayIteratorWithIndex() {
4516 index = started++;
4517 if (index < size) {
4518 value = collection[index];
4519 iterator(value, index, createCallback(value, index));
4520 }
4521 }
4522
4523 function symbolIterator() {
4524 if ((item = iter.next()).done === false) {
4525 value = item.value;
4526 iterator(value, createCallback(value, started++));
4527 }
4528 }
4529
4530 function symbolIteratorWithKey() {
4531 if ((item = iter.next()).done === false) {
4532 value = item.value;
4533 iterator(value, started, createCallback(value, started++));
4534 }
4535 }
4536
4537 function objectIterator() {
4538 if (started < size) {
4539 key = keys[started++];
4540 value = collection[key];
4541 iterator(value, createCallback(value, key));
4542 }
4543 }
4544
4545 function objectIteratorWithKey() {
4546 if (started < size) {
4547 key = keys[started++];
4548 value = collection[key];
4549 iterator(value, key, createCallback(value, key));
4550 }
4551 }
4552
4553 function createCallback(value, key) {
4554 return function(err, res) {
4555 if (key === null) {
4556 throwError();
4557 }
4558 if (err) {
4559 key = null;
4560 iterate = noop;
4561 callback = once(callback);
4562 callback(err, objectClone(result));
4563 return;
4564 }
4565 if (!!res === bool) {
4566 result[key] = value;
4567 }
4568 key = null;
4569 if (++completed === size) {
4570 iterate = throwError;
4571 callback = onlyOnce(callback);
4572 callback(null, result);
4573 } else if (sync) {
4574 nextTick(iterate);
4575 } else {
4576 sync = true;
4577 iterate();
4578 }
4579 sync = false;
4580 };
4581 }
4582 };
4583 }
4584
4585 /**
4586 * @memberof async
4587 * @namespace reduce
4588 * @param {Array|Object} collection
4589 * @param {*} result
4590 * @param {Function} iterator
4591 * @param {Function} callback
4592 * @example
4593 *
4594 * // array
4595 * var order = [];
4596 * var collection = [1, 3, 2, 4];
4597 * var iterator = function(result, num, done) {
4598 * setTimeout(function() {
4599 * order.push(num);
4600 * done(null, result + num);
4601 * }, num * 10);
4602 * };
4603 * async.reduce(collection, 0, iterator, function(err, res) {
4604 * console.log(res); // 10
4605 * console.log(order); // [1, 3, 2, 4]
4606 * });
4607 *
4608 * @example
4609 *
4610 * // array with index
4611 * var order = [];
4612 * var collection = [1, 3, 2, 4];
4613 * var iterator = function(result, num, index, done) {
4614 * setTimeout(function() {
4615 * order.push([num, index]);
4616 * done(null, result + num);
4617 * }, num * 10);
4618 * };
4619 * async.reduce(collection, '', iterator, function(err, res) {
4620 * console.log(res); // '1324'
4621 * console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]]
4622 * });
4623 *
4624 * @example
4625 *
4626 * // object
4627 * var order = [];
4628 * var object = { a: 1, b: 3, c: 2, d: 4 };
4629 * var iterator = function(result, num, done) {
4630 * setTimeout(function() {
4631 * order.push(num);
4632 * done(null, result + num);
4633 * }, num * 10);
4634 * };
4635 * async.reduce(collection, '', iterator, function(err, res) {
4636 * console.log(res); // '1324'
4637 * console.log(order); // [1, 3, 2, 4]
4638 * });
4639 *
4640 * @example
4641 *
4642 * // object with key
4643 * var order = [];
4644 * var object = { a: 1, b: 3, c: 2, d: 4 };
4645 * var iterator = function(result, num, key, done) {
4646 * setTimeout(function() {
4647 * order.push([num, key]);
4648 * done(null, result + num);
4649 * }, num * 10);
4650 * };
4651 * async.reduce(collection, 0, iterator, function(err, res) {
4652 * console.log(res); // 10
4653 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']]
4654 * });
4655 *
4656 */
4657 function reduce(collection, result, iterator, callback) {
4658 callback = onlyOnce(callback || noop);
4659 var size, key, keys, iter, iterate;
4660 var sync = false;
4661 var completed = 0;
4662
4663 if (isArray(collection)) {
4664 size = collection.length;
4665 iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
4666 } else if (!collection) {
4667 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4668 size = collection.size;
4669 iter = collection[iteratorSymbol]();
4670 iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
4671 } else if (typeof collection === obj) {
4672 keys = nativeKeys(collection);
4673 size = keys.length;
4674 iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
4675 }
4676 if (!size) {
4677 return callback(null, result);
4678 }
4679 iterate(result);
4680
4681 function arrayIterator(result) {
4682 iterator(result, collection[completed], done);
4683 }
4684
4685 function arrayIteratorWithIndex(result) {
4686 iterator(result, collection[completed], completed, done);
4687 }
4688
4689 function symbolIterator() {
4690 iterator(result, iter.next().value, done);
4691 }
4692
4693 function symbolIteratorWithKey() {
4694 iterator(result, iter.next().value, completed, done);
4695 }
4696
4697 function objectIterator(result) {
4698 iterator(result, collection[keys[completed]], done);
4699 }
4700
4701 function objectIteratorWithKey(result) {
4702 key = keys[completed];
4703 iterator(result, collection[key], key, done);
4704 }
4705
4706 function done(err, result) {
4707 if (err) {
4708 callback(err, result);
4709 } else if (++completed === size) {
4710 iterator = throwError;
4711 callback(null, result);
4712 } else if (sync) {
4713 nextTick(function() {
4714 iterate(result);
4715 });
4716 } else {
4717 sync = true;
4718 iterate(result);
4719 }
4720 sync = false;
4721 }
4722 }
4723
4724 /**
4725 * @memberof async
4726 * @namespace reduceRight
4727 * @param {Array|Object} collection
4728 * @param {*} result
4729 * @param {Function} iterator
4730 * @param {Function} callback
4731 * @example
4732 *
4733 * // array
4734 * var order = [];
4735 * var collection = [1, 3, 2, 4];
4736 * var iterator = function(result, num, done) {
4737 * setTimeout(function() {
4738 * order.push(num);
4739 * done(null, result + num);
4740 * }, num * 10);
4741 * };
4742 * async.reduceRight(collection, 0, iterator, function(err, res) {
4743 * console.log(res); // 10
4744 * console.log(order); // [4, 2, 3, 1]
4745 * });
4746 *
4747 * @example
4748 *
4749 * // array with index
4750 * var order = [];
4751 * var collection = [1, 3, 2, 4];
4752 * var iterator = function(result, num, index, done) {
4753 * setTimeout(function() {
4754 * order.push([num, index]);
4755 * done(null, result + num);
4756 * }, num * 10);
4757 * };
4758 * async.reduceRight(collection, '', iterator, function(err, res) {
4759 * console.log(res); // '4231'
4760 * console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]]
4761 * });
4762 *
4763 * @example
4764 *
4765 * // object
4766 * var order = [];
4767 * var object = { a: 1, b: 3, c: 2, d: 4 };
4768 * var iterator = function(result, num, done) {
4769 * setTimeout(function() {
4770 * order.push(num);
4771 * done(null, result + num);
4772 * }, num * 10);
4773 * };
4774 * async.reduceRight(collection, '', iterator, function(err, res) {
4775 * console.log(res); // '4231'
4776 * console.log(order); // [4, 2, 3, 1]
4777 * });
4778 *
4779 * @example
4780 *
4781 * // object with key
4782 * var order = [];
4783 * var object = { a: 1, b: 3, c: 2, d: 4 };
4784 * var iterator = function(result, num, key, done) {
4785 * setTimeout(function() {
4786 * order.push([num, key]);
4787 * done(null, result + num);
4788 * }, num * 10);
4789 * };
4790 * async.reduceRight(collection, 0, iterator, function(err, res) {
4791 * console.log(res); // 10
4792 * console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]]
4793 * });
4794 *
4795 */
4796 function reduceRight(collection, result, iterator, callback) {
4797 callback = onlyOnce(callback || noop);
4798 var resIndex, index, key, keys, iter, item, col, iterate;
4799 var sync = false;
4800
4801 if (isArray(collection)) {
4802 resIndex = collection.length;
4803 iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
4804 } else if (!collection) {
4805 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4806 resIndex = collection.size;
4807 col = Array(resIndex);
4808 iter = collection[iteratorSymbol]();
4809 index = -1;
4810 while ((item = iter.next()).done === false) {
4811 col[++index] = item.value;
4812 }
4813 collection = col;
4814 iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
4815 } else if (typeof collection === obj) {
4816 keys = nativeKeys(collection);
4817 resIndex = keys.length;
4818 iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
4819 }
4820 if (!resIndex) {
4821 return callback(null, result);
4822 }
4823 iterate(result);
4824
4825 function arrayIterator(result) {
4826 iterator(result, collection[--resIndex], done);
4827 }
4828
4829 function arrayIteratorWithIndex(result) {
4830 iterator(result, collection[--resIndex], resIndex, done);
4831 }
4832
4833 function objectIterator(result) {
4834 iterator(result, collection[keys[--resIndex]], done);
4835 }
4836
4837 function objectIteratorWithKey(result) {
4838 key = keys[--resIndex];
4839 iterator(result, collection[key], key, done);
4840 }
4841
4842 function done(err, result) {
4843 if (err) {
4844 callback(err, result);
4845 } else if (resIndex === 0) {
4846 iterate = throwError;
4847 callback(null, result);
4848 } else if (sync) {
4849 nextTick(function() {
4850 iterate(result);
4851 });
4852 } else {
4853 sync = true;
4854 iterate(result);
4855 }
4856 sync = false;
4857 }
4858 }
4859
4860 /**
4861 * @private
4862 * @param {Function} arrayEach
4863 * @param {Function} baseEach
4864 * @param {Function} symbolEach
4865 */
4866 function createTransform(arrayEach, baseEach, symbolEach) {
4867
4868 return function transform(collection, accumulator, iterator, callback) {
4869 if (arguments.length === 3) {
4870 callback = iterator;
4871 iterator = accumulator;
4872 accumulator = undefined;
4873 }
4874 callback = callback || noop;
4875 var size, keys, result;
4876 var completed = 0;
4877
4878 if (isArray(collection)) {
4879 size = collection.length;
4880 result = accumulator !== undefined ? accumulator : [];
4881 arrayEach(collection, result, iterator, done);
4882 } else if (!collection) {
4883 } else if (iteratorSymbol && collection[iteratorSymbol]) {
4884 size = collection.size;
4885 result = accumulator !== undefined ? accumulator : {};
4886 symbolEach(collection, result, iterator, done);
4887 } else if (typeof collection === obj) {
4888 keys = nativeKeys(collection);
4889 size = keys.length;
4890 result = accumulator !== undefined ? accumulator : {};
4891 baseEach(collection, result, iterator, done, keys);
4892 }
4893 if (!size) {
4894 callback(null, accumulator !== undefined ? accumulator : result || {});
4895 }
4896
4897 function done(err, bool) {
4898 if (err) {
4899 callback = once(callback);
4900 callback(err, isArray(result) ? createArray(result) : objectClone(result));
4901 } else if (++completed === size) {
4902 callback(null, result);
4903 } else if (bool === false) {
4904 callback = once(callback);
4905 callback(null, isArray(result) ? createArray(result) : objectClone(result));
4906 }
4907 }
4908 };
4909 }
4910
4911 /**
4912 * @memberof async
4913 * @namespace transformSeries
4914 * @param {Array|Object} collection
4915 * @param {Array|Object|Function} [accumulator]
4916 * @param {Function} [iterator]
4917 * @param {Function} [callback]
4918 * @example
4919 *
4920 * // array
4921 * var order = [];
4922 * var collection = [1, 3, 2, 4];
4923 * var iterator = function(result, num, done) {
4924 * setTimeout(function() {
4925 * order.push(num);
4926 * result.push(num)
4927 * done();
4928 * }, num * 10);
4929 * };
4930 * async.transformSeries(collection, iterator, function(err, res) {
4931 * console.log(res); // [1, 3, 2, 4]
4932 * console.log(order); // [1, 3, 2, 4]
4933 * });
4934 *
4935 * @example
4936 *
4937 * // array with index and accumulator
4938 * var order = [];
4939 * var collection = [1, 3, 2, 4];
4940 * var iterator = function(result, num, index, done) {
4941 * setTimeout(function() {
4942 * order.push([num, index]);
4943 * result[index] = num;
4944 * done();
4945 * }, num * 10);
4946 * };
4947 * async.transformSeries(collection, {}, iterator, function(err, res) {
4948 * console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 }
4949 * console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]]
4950 * });
4951 *
4952 * @example
4953 *
4954 * // object with accumulator
4955 * var order = [];
4956 * var object = { a: 1, b: 3, c: 2, d: 4 };
4957 * var iterator = function(result, num, done) {
4958 * setTimeout(function() {
4959 * order.push(num);
4960 * result.push(num);
4961 * done();
4962 * }, num * 10);
4963 * };
4964 * async.transformSeries(collection, [], iterator, function(err, res) {
4965 * console.log(res); // [1, 3, 2, 4]
4966 * console.log(order); // [1, 3, 2, 4]
4967 * });
4968 *
4969 * @example
4970 *
4971 * // object with key
4972 * var order = [];
4973 * var object = { a: 1, b: 3, c: 2, d: 4 };
4974 * var iterator = function(result, num, key, done) {
4975 * setTimeout(function() {
4976 * order.push([num, key]);
4977 * result[key] = num;
4978 * done();
4979 * }, num * 10);
4980 * };
4981 * async.transformSeries(collection, iterator, function(err, res) {
4982 * console.log(res); // { a: 1, b: 3, c: 2, d: 4 }
4983 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']]
4984 * });
4985 *
4986 */
4987 function transformSeries(collection, accumulator, iterator, callback) {
4988 if (arguments.length === 3) {
4989 callback = iterator;
4990 iterator = accumulator;
4991 accumulator = undefined;
4992 }
4993 callback = onlyOnce(callback || noop);
4994 var size, key, keys, iter, iterate, result;
4995 var sync = false;
4996 var completed = 0;
4997
4998 if (isArray(collection)) {
4999 size = collection.length;
5000 result = accumulator !== undefined ? accumulator : [];
5001 iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
5002 } else if (!collection) {
5003 } else if (iteratorSymbol && collection[iteratorSymbol]) {
5004 size = collection.size;
5005 iter = collection[iteratorSymbol]();
5006 result = accumulator !== undefined ? accumulator : {};
5007 iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
5008 } else if (typeof collection === obj) {
5009 keys = nativeKeys(collection);
5010 size = keys.length;
5011 result = accumulator !== undefined ? accumulator : {};
5012 iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
5013 }
5014 if (!size) {
5015 return callback(null, accumulator !== undefined ? accumulator : result || {});
5016 }
5017 iterate();
5018
5019 function arrayIterator() {
5020 iterator(result, collection[completed], done);
5021 }
5022
5023 function arrayIteratorWithIndex() {
5024 iterator(result, collection[completed], completed, done);
5025 }
5026
5027 function symbolIterator() {
5028 iterator(result, iter.next().value, done);
5029 }
5030
5031 function symbolIteratorWithKey() {
5032 iterator(result, iter.next().value, completed, done);
5033 }
5034
5035 function objectIterator() {
5036 iterator(result, collection[keys[completed]], done);
5037 }
5038
5039 function objectIteratorWithKey() {
5040 key = keys[completed];
5041 iterator(result, collection[key], key, done);
5042 }
5043
5044 function done(err, bool) {
5045 if (err) {
5046 callback(err, result);
5047 } else if (++completed === size) {
5048 iterate = throwError;
5049 callback(null, result);
5050 } else if (bool === false) {
5051 iterate = throwError;
5052 callback(null, result);
5053 } else if (sync) {
5054 nextTick(iterate);
5055 } else {
5056 sync = true;
5057 iterate();
5058 }
5059 sync = false;
5060 }
5061 }
5062
5063 /**
5064 * @memberof async
5065 * @namespace transformLimit
5066 * @param {Array|Object} collection
5067 * @param {number} limit - limit >= 1
5068 * @param {Array|Object|Function} [accumulator]
5069 * @param {Function} [iterator]
5070 * @param {Function} [callback]
5071 * @example
5072 *
5073 * // array
5074 * var order = [];
5075 * var array = [1, 5, 3, 4, 2];
5076 * var iterator = function(result, num, done) {
5077 * setTimeout(function() {
5078 * order.push(num);
5079 * result.push(num);
5080 * done();
5081 * }, num * 10);
5082 * };
5083 * async.transformLimit(array, 2, iterator, function(err, res) {
5084 * console.log(res); // [1, 3, 5, 2, 4]
5085 * console.log(order); // [1, 3, 5, 2, 4]
5086 * });
5087 *
5088 * @example
5089 *
5090 * // array with index and accumulator
5091 * var order = [];
5092 * var array = [1, 5, 3, 4, 2];
5093 * var iterator = function(result, num, index, done) {
5094 * setTimeout(function() {
5095 * order.push([num, index]);
5096 * result[index] = key;
5097 * done();
5098 * }, num * 10);
5099 * };
5100 * async.transformLimit(array, 2, {}, iterator, function(err, res) {
5101 * console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
5102 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
5103 * });
5104 *
5105 * @example
5106 *
5107 * // object with accumulator
5108 * var order = [];
5109 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5110 * var iterator = function(result, num, done) {
5111 * setTimeout(function() {
5112 * order.push(num);
5113 * result.push(num);
5114 * done();
5115 * }, num * 10);
5116 * };
5117 * async.transformLimit(object, 2, [], iterator, function(err, res) {
5118 * console.log(res); // [1, 3, 5, 2, 4]
5119 * console.log(order); // [1, 3, 5, 2, 4]
5120 * });
5121 *
5122 * @example
5123 *
5124 * // object with key
5125 * var order = [];
5126 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5127 * var iterator = function(result, num, key, done) {
5128 * setTimeout(function() {
5129 * order.push([num, key]);
5130 * result[key] = num;
5131 * done();
5132 * }, num * 10);
5133 * };
5134 * async.transformLimit(object, 2, iterator, function(err, res) {
5135 * console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 };
5136 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
5137 * });
5138 *
5139 */
5140 function transformLimit(collection, limit, accumulator, iterator, callback) {
5141 if (arguments.length === 4) {
5142 callback = iterator;
5143 iterator = accumulator;
5144 accumulator = undefined;
5145 }
5146 callback = callback || noop;
5147 var size, index, key, keys, iter, item, iterate, result;
5148 var sync = false;
5149 var started = 0;
5150 var completed = 0;
5151
5152 if (isArray(collection)) {
5153 size = collection.length;
5154 result = accumulator !== undefined ? accumulator : [];
5155 iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
5156 } else if (!collection) {
5157 } else if (iteratorSymbol && collection[iteratorSymbol]) {
5158 size = collection.size;
5159 iter = collection[iteratorSymbol]();
5160 result = accumulator !== undefined ? accumulator : {};
5161 iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
5162 } else if (typeof collection === obj) {
5163 keys = nativeKeys(collection);
5164 size = keys.length;
5165 result = accumulator !== undefined ? accumulator : {};
5166 iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
5167 }
5168 if (!size || isNaN(limit) || limit < 1) {
5169 return callback(null, accumulator !== undefined ? accumulator : result || {});
5170 }
5171 timesSync(limit > size ? size : limit, iterate);
5172
5173 function arrayIterator() {
5174 index = started++;
5175 if (index < size) {
5176 iterator(result, collection[index], onlyOnce(done));
5177 }
5178 }
5179
5180 function arrayIteratorWithIndex() {
5181 index = started++;
5182 if (index < size) {
5183 iterator(result, collection[index], index, onlyOnce(done));
5184 }
5185 }
5186
5187 function symbolIterator() {
5188 if ((item = iter.next()).done === false) {
5189 iterator(result, item.value, onlyOnce(done));
5190 }
5191 }
5192
5193 function symbolIteratorWithKey() {
5194 if ((item = iter.next()).done === false) {
5195 iterator(result, item.value, started++, onlyOnce(done));
5196 }
5197 }
5198
5199 function objectIterator() {
5200 index = started++;
5201 if (index < size) {
5202 iterator(result, collection[keys[index]], onlyOnce(done));
5203 }
5204 }
5205
5206 function objectIteratorWithKey() {
5207 index = started++;
5208 if (index < size) {
5209 key = keys[index];
5210 iterator(result, collection[key], key, onlyOnce(done));
5211 }
5212 }
5213
5214 function done(err, bool) {
5215 if (err) {
5216 iterate = noop;
5217 callback(err, isArray(result) ? createArray(result) : objectClone(result));
5218 callback = noop;
5219 } else if (++completed === size) {
5220 callback(null, result);
5221 } else if (bool === false) {
5222 iterate = noop;
5223 callback(null, isArray(result) ? createArray(result) : objectClone(result));
5224 callback = noop;
5225 } else if (sync) {
5226 nextTick(iterate);
5227 } else {
5228 sync = true;
5229 iterate();
5230 }
5231 sync = false;
5232 }
5233 }
5234
5235 /**
5236 * @private
5237 * @param {function} arrayEach
5238 * @param {function} baseEach
5239 * @param {function} symbolEach
5240 */
5241 function createSortBy(arrayEach, baseEach, symbolEach) {
5242
5243 return function sortBy(collection, iterator, callback) {
5244 callback = callback || noop;
5245 var size, result;
5246 var completed = 0;
5247
5248 if (isArray(collection)) {
5249 size = collection.length;
5250 result = Array(size);
5251 arrayEach(collection, iterator, createCallback);
5252 } else if (!collection) {
5253 } else if (iteratorSymbol && collection[iteratorSymbol]) {
5254 size = collection.size;
5255 result = Array(size);
5256 symbolEach(collection, iterator, createCallback);
5257 } else if (typeof collection === obj) {
5258 var keys = nativeKeys(collection);
5259 size = keys.length;
5260 result = Array(size);
5261 baseEach(collection, iterator, createCallback, keys);
5262 }
5263 if (!size) {
5264 callback(null, []);
5265 }
5266
5267 function createCallback(value) {
5268 var called = false;
5269 return function done(err, criteria) {
5270 if (called) {
5271 throwError();
5272 }
5273 called = true;
5274 result[completed] = {
5275 value: value,
5276 criteria: criteria
5277 };
5278 if (err) {
5279 callback = once(callback);
5280 callback(err);
5281 } else if (++completed === size) {
5282 result.sort(sortIterator);
5283 callback(null, pluck(result, 'value'));
5284 }
5285 };
5286 }
5287 };
5288 }
5289
5290 /**
5291 * @memberof async
5292 * @namespace sortBySeries
5293 * @param {Array|Object} collection
5294 * @param {Function} iterator
5295 * @param {Function} callback
5296 * @example
5297 *
5298 * // array
5299 * var order = [];
5300 * var array = [1, 3, 2];
5301 * var iterator = function(num, done) {
5302 * setTimeout(function() {
5303 * order.push(num);
5304 * done(null, num);
5305 * }, num * 10);
5306 * };
5307 * async.sortBySeries(array, iterator, function(err, res) {
5308 * console.log(res); // [1, 2, 3];
5309 * console.log(order); // [1, 3, 2]
5310 * });
5311 *
5312 * @example
5313 *
5314 * // array with index
5315 * var order = [];
5316 * var array = [1, 3, 2];
5317 * var iterator = function(num, index, done) {
5318 * setTimeout(function() {
5319 * order.push([num, index]);
5320 * done(null, num);
5321 * }, num * 10);
5322 * };
5323 * async.sortBySeries(array, iterator, function(err, res) {
5324 * console.log(res); // [1, 2, 3]
5325 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
5326 * });
5327 *
5328 * @example
5329 *
5330 * // object
5331 * var order = [];
5332 * var object = { a: 1, b: 3, c: 2 };
5333 * var iterator = function(num, done) {
5334 * setTimeout(function() {
5335 * order.push(num);
5336 * done(null, num);
5337 * }, num * 10);
5338 * };
5339 * async.sortBySeries(object, iterator, function(err, res) {
5340 * console.log(res); // [1, 2, 3]
5341 * console.log(order); // [1, 3, 2]
5342 * });
5343 *
5344 * @example
5345 *
5346 * // object with key
5347 * var order = [];
5348 * var object = { a: 1, b: 3, c: 2 };
5349 * var iterator = function(num, key, done) {
5350 * setTimeout(function() {
5351 * order.push([num, key]);
5352 * done(null, num);
5353 * }, num * 10);
5354 * };
5355 * async.sortBySeries(object, iterator, function(err, res) {
5356 * console.log(res); // [1, 2, 3]
5357 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
5358 * });
5359 *
5360 */
5361 function sortBySeries(collection, iterator, callback) {
5362 callback = onlyOnce(callback || noop);
5363 var size, key, value, keys, iter, result, iterate;
5364 var sync = false;
5365 var completed = 0;
5366
5367 if (isArray(collection)) {
5368 size = collection.length;
5369 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
5370 } else if (!collection) {
5371 } else if (iteratorSymbol && collection[iteratorSymbol]) {
5372 size = collection.size;
5373 iter = collection[iteratorSymbol]();
5374 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
5375 } else if (typeof collection === obj) {
5376 keys = nativeKeys(collection);
5377 size = keys.length;
5378 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
5379 }
5380 if (!size) {
5381 return callback(null, []);
5382 }
5383 result = Array(size);
5384 iterate();
5385
5386 function arrayIterator() {
5387 value = collection[completed];
5388 iterator(value, done);
5389 }
5390
5391 function arrayIteratorWithIndex() {
5392 value = collection[completed];
5393 iterator(value, completed, done);
5394 }
5395
5396 function symbolIterator() {
5397 value = iter.next().value;
5398 iterator(value, done);
5399 }
5400
5401 function symbolIteratorWithKey() {
5402 value = iter.next().value;
5403 iterator(value, completed, done);
5404 }
5405
5406 function objectIterator() {
5407 value = collection[keys[completed]];
5408 iterator(value, done);
5409 }
5410
5411 function objectIteratorWithKey() {
5412 key = keys[completed];
5413 value = collection[key];
5414 iterator(value, key, done);
5415 }
5416
5417 function done(err, criteria) {
5418 result[completed] = {
5419 value: value,
5420 criteria: criteria
5421 };
5422 if (err) {
5423 callback(err);
5424 } else if (++completed === size) {
5425 iterate = throwError;
5426 result.sort(sortIterator);
5427 callback(null, pluck(result, 'value'));
5428 } else if (sync) {
5429 nextTick(iterate);
5430 } else {
5431 sync = true;
5432 iterate();
5433 }
5434 sync = false;
5435 }
5436 }
5437
5438 /**
5439 * @memberof async
5440 * @namespace sortByLimit
5441 * @param {Array|Object} collection
5442 * @param {number} limit - limit >= 1
5443 * @param {Function} iterator
5444 * @param {Function} callback
5445 * @example
5446 *
5447 * // array
5448 * var order = [];
5449 * var array = [1, 5, 3, 4, 2];
5450 * var iterator = function(num, done) {
5451 * setTimeout(function() {
5452 * order.push(num);
5453 * done(null, num);
5454 * }, num * 10);
5455 * };
5456 * async.sortByLimit(array, 2, iterator, function(err, res) {
5457 * console.log(res); // [1, 2, 3, 4, 5]
5458 * console.log(order); // [1, 3, 5, 2, 4]
5459 * });
5460 *
5461 * @example
5462 *
5463 * // array with index
5464 * var order = [];
5465 * var array = [1, 5, 3, 4, 2];
5466 * var iterator = function(num, index, done) {
5467 * setTimeout(function() {
5468 * order.push([num, index]);
5469 * done(null, num);
5470 * }, num * 10);
5471 * };
5472 * async.sortByLimit(array, 2, iterator, function(err, res) {
5473 * console.log(res); // [1, 2, 3, 4, 5]
5474 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
5475 * });
5476 *
5477 * @example
5478 *
5479 * // object
5480 * var order = [];
5481 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5482 * var iterator = function(num, done) {
5483 * setTimeout(function() {
5484 * order.push(num);
5485 * done(null, num);
5486 * }, num * 10);
5487 * };
5488 * async.sortByLimit(object, 2, iterator, function(err, res) {
5489 * console.log(res); // [1, 2, 3, 4, 5]
5490 * console.log(order); // [1, 3, 5, 2, 4]
5491 * });
5492 *
5493 * @example
5494 *
5495 * // object with key
5496 * var order = [];
5497 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5498 * var iterator = function(num, key, done) {
5499 * setTimeout(function() {
5500 * order.push([num, key]);
5501 * done(null, num);
5502 * }, num * 10);
5503 * };
5504 * async.sortByLimit(object, 2, iterator, function(err, res) {
5505 * console.log(res); // [1, 2, 3, 4, 5]
5506 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
5507 * });
5508 *
5509 */
5510 function sortByLimit(collection, limit, iterator, callback) {
5511 callback = callback || noop;
5512 var size, index, key, value, keys, iter, item, result, iterate;
5513 var sync = false;
5514 var started = 0;
5515 var completed = 0;
5516
5517 if (isArray(collection)) {
5518 size = collection.length;
5519 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
5520 } else if (!collection) {
5521 } else if (iteratorSymbol && collection[iteratorSymbol]) {
5522 size = collection.size;
5523 iter = collection[iteratorSymbol]();
5524 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
5525 } else if (typeof collection === obj) {
5526 keys = nativeKeys(collection);
5527 size = keys.length;
5528 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
5529 }
5530 if (!size || isNaN(limit) || limit < 1) {
5531 return callback(null, []);
5532 }
5533 result = Array(size);
5534 timesSync(limit > size ? size : limit, iterate);
5535
5536 function arrayIterator() {
5537 if (started < size) {
5538 value = collection[started++];
5539 iterator(value, createCallback(value));
5540 }
5541 }
5542
5543 function arrayIteratorWithIndex() {
5544 index = started++;
5545 if (index < size) {
5546 value = collection[index];
5547 iterator(value, index, createCallback(value));
5548 }
5549 }
5550
5551 function symbolIterator() {
5552 if ((item = iter.next()).done === false) {
5553 value = item.value;
5554 iterator(value, createCallback(value));
5555 }
5556 }
5557
5558 function symbolIteratorWithKey() {
5559 if ((item = iter.next()).done === false) {
5560 value = item.value;
5561 iterator(value, started++, createCallback(value));
5562 }
5563 }
5564
5565 function objectIterator() {
5566 if (started < size) {
5567 value = collection[keys[started++]];
5568 iterator(value, createCallback(value));
5569 }
5570 }
5571
5572 function objectIteratorWithKey() {
5573 if (started < size) {
5574 key = keys[started++];
5575 value = collection[key];
5576 iterator(value, key, createCallback(value));
5577 }
5578 }
5579
5580 function createCallback(value) {
5581 var called = false;
5582 return function(err, criteria) {
5583 if (called) {
5584 throwError();
5585 }
5586 called = true;
5587 result[completed] = {
5588 value: value,
5589 criteria: criteria
5590 };
5591 if (err) {
5592 iterate = noop;
5593 callback(err);
5594 callback = noop;
5595 } else if (++completed === size) {
5596 result.sort(sortIterator);
5597 callback(null, pluck(result, 'value'));
5598 } else if (sync) {
5599 nextTick(iterate);
5600 } else {
5601 sync = true;
5602 iterate();
5603 }
5604 sync = false;
5605 };
5606 }
5607 }
5608
5609 /**
5610 * @memberof async
5611 * @namespace some
5612 * @param {Array|Object} collection
5613 * @param {Function} iterator
5614 * @param {Function} callback
5615 * @example
5616 *
5617 * // array
5618 * var order = [];
5619 * var array = [1, 3, 2];
5620 * var iterator = function(num, done) {
5621 * setTimeout(function() {
5622 * order.push(num);
5623 * done(null, num % 2);
5624 * }, num * 10);
5625 * };
5626 * async.some(array, iterator, function(err, res) {
5627 * console.log(res); // true
5628 * console.log(order); // [1]
5629 * });
5630 *
5631 * @example
5632 *
5633 * // array with index
5634 * var order = [];
5635 * var array = [1, 3, 2];
5636 * var iterator = function(num, index, done) {
5637 * setTimeout(function() {
5638 * order.push([num, index]);
5639 * done(null, num % 2);
5640 * }, num * 10);
5641 * };
5642 * async.some(array, iterator, function(err, res) {
5643 * console.log(res); // true
5644 * console.log(order); // [[1, 0]]
5645 * });
5646 *
5647 * @example
5648 *
5649 * // object
5650 * var order = [];
5651 * var object = { a: 1, b: 3, c: 2 };
5652 * var iterator = function(num, done) {
5653 * setTimeout(function() {
5654 * order.push(num);
5655 * done(null, num % 2);
5656 * }, num * 10);
5657 * };
5658 * async.some(object, iterator, function(err, res) {
5659 * console.log(res); // true
5660 * console.log(order); // [1]
5661 * });
5662 *
5663 * @example
5664 *
5665 * // object with key
5666 * var order = [];
5667 * var object = { a: 1, b: 3, c: 2 };
5668 * var iterator = function(num, key, done) {
5669 * setTimeout(function() {
5670 * order.push([num, key]);
5671 * done(null, num % 2);
5672 * }, num * 10);
5673 * };
5674 * async.some(object, iterator, function(err, res) {
5675 * console.log(res); // true
5676 * console.log(order); // [[1, 'a']]
5677 * });
5678 *
5679 */
5680 function some(collection, iterator, callback) {
5681 callback = callback || noop;
5682 detect(collection, iterator, done);
5683
5684 function done(err, res) {
5685 if (err) {
5686 return callback(err);
5687 }
5688 callback(null, !!res);
5689 }
5690 }
5691
5692 /**
5693 * @memberof async
5694 * @namespace someSeries
5695 * @param {Array|Object} collection
5696 * @param {Function} iterator
5697 * @param {Function} callback
5698 * @example
5699 *
5700 * // array
5701 * var order = [];
5702 * var array = [1, 3, 2];
5703 * var iterator = function(num, done) {
5704 * setTimeout(function() {
5705 * order.push(num);
5706 * done(null, num % 2);
5707 * }, num * 10);
5708 * };
5709 * async.someSeries(array, iterator, function(err, res) {
5710 * console.log(res); // true
5711 * console.log(order); // [1]
5712 * });
5713 *
5714 * @example
5715 *
5716 * // array with index
5717 * var order = [];
5718 * var array = [1, 3, 2];
5719 * var iterator = function(num, index, done) {
5720 * setTimeout(function() {
5721 * order.push([num, index]);
5722 * done(null, num % 2);
5723 * }, num * 10);
5724 * };
5725 * async.someSeries(array, iterator, function(err, res) {
5726 * console.log(res); // true
5727 * console.log(order); // [[1, 0]]
5728 * });
5729 *
5730 * @example
5731 *
5732 * // object
5733 * var order = [];
5734 * var object = { a: 1, b: 3, c: 2 };
5735 * var iterator = function(num, done) {
5736 * setTimeout(function() {
5737 * order.push(num);
5738 * done(null, num % 2);
5739 * }, num * 10);
5740 * };
5741 * async.someSeries(object, iterator, function(err, res) {
5742 * console.log(res); // true
5743 * console.log(order); // [1]
5744 * });
5745 *
5746 * @example
5747 *
5748 * // object with key
5749 * var order = [];
5750 * var object = { a: 1, b: 3, c: 2 };
5751 * var iterator = function(num, key, done) {
5752 * setTimeout(function() {
5753 * order.push([num, key]);
5754 * done(null, num % 2);
5755 * }, num * 10);
5756 * };
5757 * async.someSeries(object, iterator, function(err, res) {
5758 * console.log(res); // true
5759 * console.log(order); // [[1, 'a']]
5760 * });
5761 *
5762 */
5763 function someSeries(collection, iterator, callback) {
5764 callback = callback || noop;
5765 detectSeries(collection, iterator, done);
5766
5767 function done(err, res) {
5768 if (err) {
5769 return callback(err);
5770 }
5771 callback(null, !!res);
5772 }
5773 }
5774
5775 /**
5776 * @memberof async
5777 * @namespace someLimit
5778 * @param {Array|Object} collection
5779 * @param {number} limit - limit >= 1
5780 * @param {Function} iterator
5781 * @param {Function} callback
5782 * @example
5783 *
5784 * // array
5785 * var order = [];
5786 * var array = [1, 5, 3, 4, 2];
5787 * var iterator = function(num, done) {
5788 * setTimeout(function() {
5789 * order.push(num);
5790 * done(null, num % 2);
5791 * }, num * 10);
5792 * };
5793 * async.someLimit(array, 2, iterator, function(err, res) {
5794 * console.log(res); // true
5795 * console.log(order); // [1]
5796 * });
5797 *
5798 * @example
5799 *
5800 * // array with index
5801 * var order = [];
5802 * var array = [1, 5, 3, 4, 2];
5803 * var iterator = function(num, index, done) {
5804 * setTimeout(function() {
5805 * order.push([num, index]);
5806 * done(null, num % 2);
5807 * }, num * 10);
5808 * };
5809 * async.someLimit(array, 2, iterator, function(err, res) {
5810 * console.log(res); // true
5811 * console.log(order); // [[1, 0]]
5812 * });
5813 *
5814 * @example
5815 *
5816 * // object
5817 * var order = [];
5818 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5819 * var iterator = function(num, done) {
5820 * setTimeout(function() {
5821 * order.push(num);
5822 * done(null, num % 2);
5823 * }, num * 10);
5824 * };
5825 * async.someLimit(object, 2, iterator, function(err, res) {
5826 * console.log(res); // true
5827 * console.log(order); // [1]
5828 * });
5829 *
5830 * @example
5831 *
5832 * // object with key
5833 * var order = [];
5834 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
5835 * var iterator = function(num, key, done) {
5836 * setTimeout(function() {
5837 * order.push([num, key]);
5838 * done(null, num % 2);
5839 * }, num * 10);
5840 * };
5841 * async.someLimit(object, 2, iterator, function(err, res) {
5842 * console.log(res); // true
5843 * console.log(order); // [[1, 'a']]
5844 * });
5845 *
5846 */
5847 function someLimit(collection, limit, iterator, callback) {
5848 callback = callback || noop;
5849 detectLimit(collection, limit, iterator, done);
5850
5851 function done(err, res) {
5852 if (err) {
5853 return callback(err);
5854 }
5855 callback(null, !!res);
5856 }
5857 }
5858
5859 /**
5860 * @private
5861 * @param {Function} arrayEach
5862 * @param {Function} baseEach
5863 * @param {Function} symbolEach
5864 */
5865 function createEvery(arrayEach, baseEach, symbolEach) {
5866
5867 var deny = createDetect(arrayEach, baseEach, symbolEach, false);
5868
5869 return function every(collection, iterator, callback) {
5870 callback = callback || noop;
5871 deny(collection, iterator, done);
5872
5873 function done(err, res) {
5874 if (err) {
5875 return callback(err);
5876 }
5877 callback(null, !res);
5878 }
5879 };
5880 }
5881
5882 /**
5883 * @private
5884 */
5885 function createEverySeries() {
5886
5887 var denySeries = createDetectSeries(false);
5888
5889 return function everySeries(collection, iterator, callback) {
5890 callback = callback || noop;
5891 denySeries(collection, iterator, done);
5892
5893 function done(err, res) {
5894 if (err) {
5895 return callback(err);
5896 }
5897 callback(null, !res);
5898 }
5899 };
5900 }
5901
5902 /**
5903 * @private
5904 */
5905 function createEveryLimit() {
5906
5907 var denyLimit = createDetectLimit(false);
5908
5909 return function everyLimit(collection, limit, iterator, callback) {
5910 callback = callback || noop;
5911 denyLimit(collection, limit, iterator, done);
5912
5913 function done(err, res) {
5914 if (err) {
5915 return callback(err);
5916 }
5917 callback(null, !res);
5918 }
5919 };
5920 }
5921
5922 /**
5923 * @private
5924 * @param {Function} arrayEach
5925 * @param {Function} baseEach
5926 * @param {Function} symbolEach
5927 */
5928 function createConcat(arrayEach, baseEach, symbolEach) {
5929
5930 return function concat(collection, iterator, callback) {
5931 callback = callback || noop;
5932 var size, result;
5933 var completed = 0;
5934
5935 if (isArray(collection)) {
5936 size = collection.length;
5937 result = Array(size);
5938 arrayEach(collection, iterator, createCallback);
5939 } else if (!collection) {
5940 } else if (iteratorSymbol && collection[iteratorSymbol]) {
5941 size = collection.size;
5942 result = Array(size);
5943 symbolEach(collection, iterator, createCallback);
5944 } else if (typeof collection === obj) {
5945 var keys = nativeKeys(collection);
5946 size = keys.length;
5947 result = Array(size);
5948 baseEach(collection, iterator, createCallback, keys);
5949 }
5950 if (!size) {
5951 callback(null, []);
5952 }
5953
5954 function createCallback(index) {
5955 return function done(err, res) {
5956 if (index === null) {
5957 throwError();
5958 }
5959 if (err) {
5960 index = null;
5961 callback = once(callback);
5962 arrayEachSync(result, function(array, index) {
5963 if (array === undefined) {
5964 result[index] = noop;
5965 }
5966 });
5967 callback(err, makeConcatResult(result));
5968 return;
5969 }
5970 switch (arguments.length) {
5971 case 0:
5972 case 1:
5973 result[index] = noop;
5974 break;
5975 case 2:
5976 result[index] = res;
5977 break;
5978 default:
5979 result[index] = slice(arguments, 1);
5980 break;
5981 }
5982 index = null;
5983 if (++completed === size) {
5984 callback(null, makeConcatResult(result));
5985 }
5986 };
5987 }
5988 };
5989 }
5990
5991 /**
5992 * @memberof async
5993 * @namespace concatSeries
5994 * @param {Array|Object} collection
5995 * @param {Function} iterator
5996 * @param {Function} callback
5997 * @example
5998 *
5999 * // array
6000 * var order = [];
6001 * var array = [1, 3, 2];
6002 * var iterator = function(num, done) {
6003 * setTimeout(function() {
6004 * order.push(num);
6005 * done(null, [num]);
6006 * }, num * 10);
6007 * };
6008 * async.concatSeries(array, iterator, function(err, res) {
6009 * console.log(res); // [1, 3, 2];
6010 * console.log(order); // [1, 3, 2]
6011 * });
6012 *
6013 * @example
6014 *
6015 * // array with index
6016 * var order = [];
6017 * var array = [1, 3, 2];
6018 * var iterator = function(num, index, done) {
6019 * setTimeout(function() {
6020 * order.push([num, index]);
6021 * done(null, [num]);
6022 * }, num * 10);
6023 * };
6024 * async.concatSeries(array, iterator, function(err, res) {
6025 * console.log(res); // [1, 3, 2]
6026 * console.log(order); // [[1, 0], [3, 1], [2, 2]]
6027 * });
6028 *
6029 * @example
6030 *
6031 * // object
6032 * var order = [];
6033 * var object = { a: 1, b: 3, c: 2 };
6034 * var iterator = function(num, done) {
6035 * setTimeout(function() {
6036 * order.push(num);
6037 * done(null, [num]);
6038 * }, num * 10);
6039 * };
6040 * async.concatSeries(object, iterator, function(err, res) {
6041 * console.log(res); // [1, 3, 2]
6042 * console.log(order); // [1, 3, 2]
6043 * });
6044 *
6045 * @example
6046 *
6047 * // object with key
6048 * var order = [];
6049 * var object = { a: 1, b: 3, c: 2 };
6050 * var iterator = function(num, key, done) {
6051 * setTimeout(function() {
6052 * order.push([num, key]);
6053 * done(null, [num]);
6054 * }, num * 10);
6055 * };
6056 * async.concatSeries(object, iterator, function(err, res) {
6057 * console.log(res); // [1, 3, 2]
6058 * console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
6059 * });
6060 *
6061 */
6062 function concatSeries(collection, iterator, callback) {
6063 callback = onlyOnce(callback || noop);
6064 var size, key, keys, iter, values, iterate;
6065 var sync = false;
6066 var result = [];
6067 var completed = 0;
6068
6069 if (isArray(collection)) {
6070 size = collection.length;
6071 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6072 } else if (!collection) {
6073 } else if (iteratorSymbol && collection[iteratorSymbol]) {
6074 size = collection.size;
6075 iter = collection[iteratorSymbol]();
6076 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6077 } else if (typeof collection === obj) {
6078 keys = nativeKeys(collection);
6079 size = keys.length;
6080 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6081 }
6082 if (!size) {
6083 return callback(null, result);
6084 }
6085 iterate();
6086
6087 function arrayIterator() {
6088 iterator(collection[completed], done);
6089 }
6090
6091 function arrayIteratorWithIndex() {
6092 iterator(collection[completed], completed, done);
6093 }
6094
6095 function symbolIterator() {
6096 iterator(iter.next().value, done);
6097 }
6098
6099 function symbolIteratorWithKey() {
6100 values = iter.next().value;
6101 iterator(values, completed, done);
6102 }
6103
6104 function objectIterator() {
6105 iterator(collection[keys[completed]], done);
6106 }
6107
6108 function objectIteratorWithKey() {
6109 key = keys[completed];
6110 iterator(collection[key], key, done);
6111 }
6112
6113 function done(err, array) {
6114 if (isArray(array)) {
6115 nativePush.apply(result, array);
6116 } else if (arguments.length >= 2) {
6117 nativePush.apply(result, slice(arguments, 1));
6118 }
6119 if (err) {
6120 callback(err, result);
6121 } else if (++completed === size) {
6122 iterate = throwError;
6123 callback(null, result);
6124 } else if (sync) {
6125 nextTick(iterate);
6126 } else {
6127 sync = true;
6128 iterate();
6129 }
6130 sync = false;
6131 }
6132 }
6133
6134 /**
6135 * @memberof async
6136 * @namespace concatLimit
6137 * @param {Array|Object} collection
6138 * @param {number} limit - limit >= 1
6139 * @param {Function} iterator
6140 * @param {Function} callback
6141 * @example
6142 *
6143 * // array
6144 * var order = [];
6145 * var array = [1, 5, 3, 4, 2];
6146 * var iterator = function(num, done) {
6147 * setTimeout(function() {
6148 * order.push(num);
6149 * done(null, [num]);
6150 * }, num * 10);
6151 * };
6152 * async.concatLimit(array, 2, iterator, function(err, res) {
6153 * console.log(res); // [1, 3, 5, 2, 4]
6154 * console.log(order); // [1, 3, 5, 2, 4]
6155 * });
6156 *
6157 * @example
6158 *
6159 * // array with index
6160 * var order = [];
6161 * var array = [1, 5, 3, 4, 2];
6162 * var iterator = function(num, index, done) {
6163 * setTimeout(function() {
6164 * order.push([num, index]);
6165 * done(null, [num]);
6166 * }, num * 10);
6167 * };
6168 * async.cocnatLimit(array, 2, iterator, function(err, res) {
6169 * console.log(res); // [1, 3, 5, 2, 4]
6170 * console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
6171 * });
6172 *
6173 * @example
6174 *
6175 * // object
6176 * var order = [];
6177 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
6178 * var iterator = function(num, done) {
6179 * setTimeout(function() {
6180 * order.push(num);
6181 * done(null, [num]);
6182 * }, num * 10);
6183 * };
6184 * async.concatLimit(object, 2, iterator, function(err, res) {
6185 * console.log(res); // [1, 3, 5, 2, 4]
6186 * console.log(order); // [1, 3, 5, 2, 4]
6187 * });
6188 *
6189 * @example
6190 *
6191 * // object with key
6192 * var order = [];
6193 * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
6194 * var iterator = function(num, key, done) {
6195 * setTimeout(function() {
6196 * order.push([num, key]);
6197 * done(null, num);
6198 * }, num * 10);
6199 * };
6200 * async.cocnatLimit(object, 2, iterator, function(err, res) {
6201 * console.log(res); // [1, 3, 5, 2, 4]
6202 * console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
6203 * });
6204 *
6205 */
6206 function concatLimit(collection, limit, iterator, callback) {
6207 callback = callback || noop;
6208 var size, key, iter, item, iterate;
6209 var sync = false;
6210 var started = 0;
6211 var completed = 0;
6212
6213 if (isArray(collection)) {
6214 size = collection.length;
6215 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6216 } else if (!collection) {
6217 } else if (iteratorSymbol && collection[iteratorSymbol]) {
6218 size = collection.size;
6219 iter = collection[iteratorSymbol]();
6220 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6221 } else if (typeof collection === obj) {
6222 var keys = nativeKeys(collection);
6223 size = keys.length;
6224 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6225 }
6226 if (!size || isNaN(limit) || limit < 1) {
6227 return callback(null, []);
6228 }
6229 var result = Array(size);
6230 timesSync(limit > size ? size : limit, iterate);
6231
6232 function arrayIterator() {
6233 if (started < size) {
6234 iterator(collection[started], createCallback(started++));
6235 }
6236 }
6237
6238 function arrayIteratorWithIndex() {
6239 if (started < size) {
6240 iterator(collection[started], started, createCallback(started++));
6241 }
6242 }
6243
6244 function symbolIterator() {
6245 if ((item = iter.next()).done === false) {
6246 iterator(item.value, createCallback(started++));
6247 }
6248 }
6249
6250 function symbolIteratorWithKey() {
6251 if ((item = iter.next()).done === false) {
6252 iterator(item.value, started, createCallback(started++));
6253 }
6254 }
6255
6256 function objectIterator() {
6257 if (started < size) {
6258 iterator(collection[keys[started]], createCallback(started++));
6259 }
6260 }
6261
6262 function objectIteratorWithKey() {
6263 if (started < size) {
6264 key = keys[started];
6265 iterator(collection[key], key, createCallback(started++));
6266 }
6267 }
6268
6269 function createCallback(index) {
6270 return function(err, res) {
6271 if (index === null) {
6272 throwError();
6273 }
6274 if (err) {
6275 index = null;
6276 iterate = noop;
6277 callback = once(callback);
6278 arrayEachSync(result, function(array, index) {
6279 if (array === undefined) {
6280 result[index] = noop;
6281 }
6282 });
6283 callback(err, makeConcatResult(result));
6284 return;
6285 }
6286 switch (arguments.length) {
6287 case 0:
6288 case 1:
6289 result[index] = noop;
6290 break;
6291 case 2:
6292 result[index] = res;
6293 break;
6294 default:
6295 result[index] = slice(arguments, 1);
6296 break;
6297 }
6298 index = null;
6299 if (++completed === size) {
6300 iterate = throwError;
6301 callback(null, makeConcatResult(result));
6302 callback = throwError;
6303 } else if (sync) {
6304 nextTick(iterate);
6305 } else {
6306 sync = true;
6307 iterate();
6308 }
6309 sync = false;
6310 };
6311 }
6312 }
6313
6314 /**
6315 * @private
6316 * @param {Function} arrayEach
6317 * @param {Function} baseEach
6318 * @param {Function} symbolEach
6319 */
6320 function createGroupBy(arrayEach, baseEach, symbolEach) {
6321
6322 return function groupBy(collection, iterator, callback) {
6323 callback = callback || noop;
6324 var size;
6325 var completed = 0;
6326 var result = {};
6327
6328 if (isArray(collection)) {
6329 size = collection.length;
6330 arrayEach(collection, iterator, createCallback);
6331 } else if (!collection) {
6332 } else if (iteratorSymbol && collection[iteratorSymbol]) {
6333 size = collection.size;
6334 symbolEach(collection, iterator, createCallback);
6335 } else if (typeof collection === obj) {
6336 var keys = nativeKeys(collection);
6337 size = keys.length;
6338 baseEach(collection, iterator, createCallback, keys);
6339 }
6340 if (!size) {
6341 callback(null, {});
6342 }
6343
6344 function createCallback(value) {
6345 var called = false;
6346 return function done(err, key) {
6347 if (called) {
6348 throwError();
6349 }
6350 called = true;
6351 if (err) {
6352 callback = once(callback);
6353 callback(err, objectClone(result));
6354 return;
6355 }
6356 var array = result[key];
6357 if (!array) {
6358 array = result[key] = [value];
6359 } else {
6360 array.push(value);
6361 }
6362 if (++completed === size) {
6363 callback(null, result);
6364 }
6365 };
6366 }
6367 };
6368 }
6369
6370 /**
6371 * @memberof async
6372 * @namespace groupBySeries
6373 * @param {Array|Object} collection
6374 * @param {Function} iterator
6375 * @param {Function} callback
6376 * @example
6377 *
6378 * // array
6379 * var order = [];
6380 * var array = [4.2, 6.4, 6.1];
6381 * var iterator = function(num, done) {
6382 * setTimeout(function() {
6383 * order.push(num);
6384 * done(null, Math.floor(num));
6385 * }, num * 10);
6386 * };
6387 * async.groupBySeries(array, iterator, function(err, res) {
6388 * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6389 * console.log(order); // [4.2, 6.4, 6.1]
6390 * });
6391 *
6392 * @example
6393 *
6394 * // array with index
6395 * var order = [];
6396 * var array = [4.2, 6.4, 6.1];
6397 * var iterator = function(num, index, done) {
6398 * setTimeout(function() {
6399 * order.push([num, index]);
6400 * done(null, Math.floor(num));
6401 * }, num * 10);
6402 * };
6403 * async.groupBySeries(array, iterator, function(err, res) {
6404 * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6405 * console.log(order); // [[4.2, 0], [6.4, 1], [6.1, 2]]
6406 * });
6407 *
6408 * @example
6409 *
6410 * // object
6411 * var order = [];
6412 * var object = { a: 4.2, b: 6.4, c: 6.1 };
6413 * var iterator = function(num, done) {
6414 * setTimeout(function() {
6415 * order.push(num);
6416 * done(null, Math.floor(num));
6417 * }, num * 10);
6418 * };
6419 * async.groupBySeries(object, iterator, function(err, res) {
6420 * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6421 * console.log(order); // [4.2, 6.4, 6.1]
6422 * });
6423 *
6424 * @example
6425 *
6426 * // object with key
6427 * var order = [];
6428 * var object = { a: 4.2, b: 6.4, c: 6.1 };
6429 * var iterator = function(num, key, done) {
6430 * setTimeout(function() {
6431 * order.push([num, key]);
6432 * done(null, Math.floor(num));
6433 * }, num * 10);
6434 * };
6435 * async.groupBySeries(object, iterator, function(err, res) {
6436 * console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
6437 * console.log(order); // [[4.2, 'a'], [6.4, 'b'], [6.1, 'c']]
6438 * });
6439 *
6440 */
6441 function groupBySeries(collection, iterator, callback) {
6442 callback = onlyOnce(callback || noop);
6443 var size, key, value, keys, iter, iterate;
6444 var sync = false;
6445 var completed = 0;
6446 var result = {};
6447
6448 if (isArray(collection)) {
6449 size = collection.length;
6450 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6451 } else if (!collection) {
6452 } else if (iteratorSymbol && collection[iteratorSymbol]) {
6453 size = collection.size;
6454 iter = collection[iteratorSymbol]();
6455 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6456 } else if (typeof collection === obj) {
6457 keys = nativeKeys(collection);
6458 size = keys.length;
6459 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6460 }
6461 if (!size) {
6462 return callback(null, result);
6463 }
6464 iterate();
6465
6466 function arrayIterator() {
6467 value = collection[completed];
6468 iterator(value, done);
6469 }
6470
6471 function arrayIteratorWithIndex() {
6472 value = collection[completed];
6473 iterator(value, completed, done);
6474 }
6475
6476 function symbolIterator() {
6477 value = iter.next().value;
6478 iterator(value, done);
6479 }
6480
6481 function symbolIteratorWithKey() {
6482 value = iter.next().value;
6483 iterator(value, completed, done);
6484 }
6485
6486 function objectIterator() {
6487 value = collection[keys[completed]];
6488 iterator(value, done);
6489 }
6490
6491 function objectIteratorWithKey() {
6492 key = keys[completed];
6493 value = collection[key];
6494 iterator(value, key, done);
6495 }
6496
6497 function done(err, key) {
6498 if (err) {
6499 iterate = throwError;
6500 callback = onlyOnce(callback);
6501 callback(err, objectClone(result));
6502 return;
6503 }
6504 var array = result[key];
6505 if (!array) {
6506 array = result[key] = [value];
6507 } else {
6508 array.push(value);
6509 }
6510 if (++completed === size) {
6511 iterate = throwError;
6512 callback(null, result);
6513 } else if (sync) {
6514 nextTick(iterate);
6515 } else {
6516 sync = true;
6517 iterate();
6518 }
6519 sync = false;
6520 }
6521 }
6522
6523 /**
6524 * @memberof async
6525 * @namespace groupByLimit
6526 * @param {Array|Object} collection
6527 * @param {Function} iterator
6528 * @param {Function} callback
6529 * @example
6530 *
6531 * // array
6532 * var order = [];
6533 * var array = [1.1, 5.9, 3.2, 3.9, 2.1];
6534 * var iterator = function(num, done) {
6535 * setTimeout(function() {
6536 * order.push(num);
6537 * done(null, Math.floor(num));
6538 * }, num * 10);
6539 * };
6540 * async.groupByLimit(array, 2, iterator, function(err, res) {
6541 * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6542 * console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9]
6543 * });
6544 *
6545 * @example
6546 *
6547 * // array with index
6548 * var order = [];
6549 * var array = [1.1, 5.9, 3.2, 3.9, 2.1];
6550 * var iterator = function(num, index, done) {
6551 * setTimeout(function() {
6552 * order.push([num, index]);
6553 * done(null, Math.floor(num));
6554 * }, num * 10);
6555 * };
6556 * async.groupByLimit(array, 2, iterator, function(err, res) {
6557 * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6558 * console.log(order); // [[1.1, 0], [3.2, 2], [5.9, 1], [2.1, 4], [3.9, 3]]
6559 * });
6560 *
6561 * @example
6562 *
6563 * // object
6564 * var order = [];
6565 * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 }
6566 * var iterator = function(num, done) {
6567 * setTimeout(function() {
6568 * order.push(num);
6569 * done(null, Math.floor(num));
6570 * }, num * 10);
6571 * };
6572 * async.groupByLimit(object, 2, iterator, function(err, res) {
6573 * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6574 * console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9]
6575 * });
6576 *
6577 * @example
6578 *
6579 * // object with key
6580 * var order = [];
6581 * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 }
6582 * var iterator = function(num, key, done) {
6583 * setTimeout(function() {
6584 * order.push([num, key]);
6585 * done(null, Math.floor(num));
6586 * }, num * 10);
6587 * };
6588 * async.groupByLimit(object, 2, iterator, function(err, res) {
6589 * console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
6590 * console.log(order); // [[1.1, 'a'], [3.2, 'c'], [5.9, 'b'], [2.1, 'e'], [3.9, 'd']]
6591 * });
6592 *
6593 */
6594 function groupByLimit(collection, limit, iterator, callback) {
6595 callback = callback || noop;
6596 var size, index, key, value, keys, iter, item, iterate;
6597 var sync = false;
6598 var started = 0;
6599 var completed = 0;
6600 var result = {};
6601
6602 if (isArray(collection)) {
6603 size = collection.length;
6604 iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
6605 } else if (!collection) {
6606 } else if (iteratorSymbol && collection[iteratorSymbol]) {
6607 size = collection.size;
6608 iter = collection[iteratorSymbol]();
6609 iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
6610 } else if (typeof collection === obj) {
6611 keys = nativeKeys(collection);
6612 size = keys.length;
6613 iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
6614 }
6615 if (!size || isNaN(limit) || limit < 1) {
6616 return callback(null, result);
6617 }
6618 timesSync(limit > size ? size : limit, iterate);
6619
6620 function arrayIterator() {
6621 if (started < size) {
6622 value = collection[started++];
6623 iterator(value, createCallback(value));
6624 }
6625 }
6626
6627 function arrayIteratorWithIndex() {
6628 index = started++;
6629 if (index < size) {
6630 value = collection[index];
6631 iterator(value, index, createCallback(value));
6632 }
6633 }
6634
6635 function symbolIterator() {
6636 if ((item = iter.next()).done === false) {
6637 value = item.value;
6638 iterator(value, createCallback(value));
6639 }
6640 }
6641
6642 function symbolIteratorWithKey() {
6643 if ((item = iter.next()).done === false) {
6644 value = item.value;
6645 iterator(value, started++, createCallback(value));
6646 }
6647 }
6648
6649 function objectIterator() {
6650 if (started < size) {
6651 value = collection[keys[started++]];
6652 iterator(value, createCallback(value));
6653 }
6654 }
6655
6656 function objectIteratorWithKey() {
6657 if (started < size) {
6658 key = keys[started++];
6659 value = collection[key];
6660 iterator(value, key, createCallback(value));
6661 }
6662 }
6663
6664 function createCallback(value) {
6665 var called = false;
6666 return function(err, key) {
6667 if (called) {
6668 throwError();
6669 }
6670 called = true;
6671 if (err) {
6672 iterate = noop;
6673 callback = once(callback);
6674 callback(err, objectClone(result));
6675 return;
6676 }
6677 var array = result[key];
6678 if (!array) {
6679 result[key] = [value];
6680 } else {
6681 array.push(value);
6682 }
6683 if (++completed === size) {
6684 callback(null, result);
6685 } else if (sync) {
6686 nextTick(iterate);
6687 } else {
6688 sync = true;
6689 iterate();
6690 }
6691 sync = false;
6692 };
6693 }
6694 }
6695
6696 /**
6697 * @private
6698 * @param {Function} arrayEach
6699 * @param {Function} baseEach
6700 */
6701 function createParallel(arrayEach, baseEach) {
6702
6703 return function parallel(tasks, callback) {
6704 callback = callback || noop;
6705 var size, keys, result;
6706 var completed = 0;
6707
6708 if (isArray(tasks)) {
6709 size = tasks.length;
6710 result = Array(size);
6711 arrayEach(tasks, createCallback);
6712 } else if (tasks && typeof tasks === obj) {
6713 keys = nativeKeys(tasks);
6714 size = keys.length;
6715 result = {};
6716 baseEach(tasks, createCallback, keys);
6717 }
6718 if (!size) {
6719 callback(null, result);
6720 }
6721
6722 function createCallback(key) {
6723 return function(err, res) {
6724 if (key === null) {
6725 throwError();
6726 }
6727 if (err) {
6728 key = null;
6729 callback = once(callback);
6730 callback(err, result);
6731 return;
6732 }
6733 result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
6734 key = null;
6735 if (++completed === size) {
6736 callback(null, result);
6737 }
6738 };
6739 }
6740 };
6741 }
6742
6743 /**
6744 * @memberof async
6745 * @namespace series
6746 * @param {Array|Object} tasks - functions
6747 * @param {Function} callback
6748 * @example
6749 *
6750 * var order = [];
6751 * var tasks = [
6752 * function(done) {
6753 * setTimeout(function() {
6754 * order.push(1);
6755 * done(null, 1);
6756 * }, 10);
6757 * },
6758 * function(done) {
6759 * setTimeout(function() {
6760 * order.push(2);
6761 * done(null, 2);
6762 * }, 30);
6763 * },
6764 * function(done) {
6765 * setTimeout(function() {
6766 * order.push(3);
6767 * done(null, 3);
6768 * }, 40);
6769 * },
6770 * function(done) {
6771 * setTimeout(function() {
6772 * order.push(4);
6773 * done(null, 4);
6774 * }, 20);
6775 * }
6776 * ];
6777 * async.series(tasks, function(err, res) {
6778 * console.log(res); // [1, 2, 3, 4];
6779 * console.log(order); // [1, 2, 3, 4]
6780 * });
6781 *
6782 * @example
6783 *
6784 * var order = [];
6785 * var tasks = {
6786 * 'a': function(done) {
6787 * setTimeout(function() {
6788 * order.push(1);
6789 * done(null, 1);
6790 * }, 10);
6791 * },
6792 * 'b': function(done) {
6793 * setTimeout(function() {
6794 * order.push(2);
6795 * done(null, 2);
6796 * }, 30);
6797 * },
6798 * 'c': function(done) {
6799 * setTimeout(function() {
6800 * order.push(3);
6801 * done(null, 3);
6802 * }, 40);
6803 * },
6804 * 'd': function(done) {
6805 * setTimeout(function() {
6806 * order.push(4);
6807 * done(null, 4);
6808 * }, 20);
6809 * }
6810 * };
6811 * async.series(tasks, function(err, res) {
6812 * console.log(res); // { a: 1, b: 2, c: 3, d:4 }
6813 * console.log(order); // [1, 4, 2, 3]
6814 * });
6815 *
6816 */
6817 function series(tasks, callback) {
6818 callback = callback || noop;
6819 var size, key, keys, result, iterate;
6820 var sync = false;
6821 var completed = 0;
6822
6823 if (isArray(tasks)) {
6824 size = tasks.length;
6825 result = Array(size);
6826 iterate = arrayIterator;
6827 } else if (tasks && typeof tasks === obj) {
6828 keys = nativeKeys(tasks);
6829 size = keys.length;
6830 result = {};
6831 iterate = objectIterator;
6832 } else {
6833 return callback(null);
6834 }
6835 if (!size) {
6836 return callback(null, result);
6837 }
6838 iterate();
6839
6840 function arrayIterator() {
6841 key = completed;
6842 tasks[completed](done);
6843 }
6844
6845 function objectIterator() {
6846 key = keys[completed];
6847 tasks[key](done);
6848 }
6849
6850 function done(err, res) {
6851 if (err) {
6852 iterate = throwError;
6853 callback = onlyOnce(callback);
6854 callback(err, result);
6855 return;
6856 }
6857 result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
6858 if (++completed === size) {
6859 iterate = throwError;
6860 callback(null, result);
6861 } else if (sync) {
6862 nextTick(iterate);
6863 } else {
6864 sync = true;
6865 iterate();
6866 }
6867 sync = false;
6868 }
6869 }
6870
6871 /**
6872 * @memberof async
6873 * @namespace parallelLimit
6874 * @param {Array|Object} tasks - functions
6875 * @param {number} limit - limit >= 1
6876 * @param {Function} callback
6877 * @example
6878 *
6879 * var order = [];
6880 * var tasks = [
6881 * function(done) {
6882 * setTimeout(function() {
6883 * order.push(1);
6884 * done(null, 1);
6885 * }, 10);
6886 * },
6887 * function(done) {
6888 * setTimeout(function() {
6889 * order.push(2);
6890 * done(null, 2);
6891 * }, 50);
6892 * },
6893 * function(done) {
6894 * setTimeout(function() {
6895 * order.push(3);
6896 * done(null, 3);
6897 * }, 30);
6898 * },
6899 * function(done) {
6900 * setTimeout(function() {
6901 * order.push(4);
6902 * done(null, 4);
6903 * }, 40);
6904 * }
6905 * ];
6906 * async.parallelLimit(tasks, 2, function(err, res) {
6907 * console.log(res); // [1, 2, 3, 4];
6908 * console.log(order); // [1, 3, 2, 4]
6909 * });
6910 *
6911 * @example
6912 *
6913 * var order = [];
6914 * var tasks = {
6915 * 'a': function(done) {
6916 * setTimeout(function() {
6917 * order.push(1);
6918 * done(null, 1);
6919 * }, 10);
6920 * },
6921 * 'b': function(done) {
6922 * setTimeout(function() {
6923 * order.push(2);
6924 * done(null, 2);
6925 * }, 50);
6926 * },
6927 * 'c': function(done) {
6928 * setTimeout(function() {
6929 * order.push(3);
6930 * done(null, 3);
6931 * }, 20);
6932 * },
6933 * 'd': function(done) {
6934 * setTimeout(function() {
6935 * order.push(4);
6936 * done(null, 4);
6937 * }, 40);
6938 * }
6939 * };
6940 * async.parallelLimit(tasks, 2, function(err, res) {
6941 * console.log(res); // { a: 1, b: 2, c: 3, d:4 }
6942 * console.log(order); // [1, 3, 2, 4]
6943 * });
6944 *
6945 */
6946 function parallelLimit(tasks, limit, callback) {
6947 callback = callback || noop;
6948 var size, index, key, keys, result, iterate;
6949 var sync = false;
6950 var started = 0;
6951 var completed = 0;
6952
6953 if (isArray(tasks)) {
6954 size = tasks.length;
6955 result = Array(size);
6956 iterate = arrayIterator;
6957 } else if (tasks && typeof tasks === obj) {
6958 keys = nativeKeys(tasks);
6959 size = keys.length;
6960 result = {};
6961 iterate = objectIterator;
6962 }
6963 if (!size || isNaN(limit) || limit < 1) {
6964 return callback(null, result);
6965 }
6966 timesSync(limit > size ? size : limit, iterate);
6967
6968 function arrayIterator() {
6969 index = started++;
6970 if (index < size) {
6971 tasks[index](createCallback(index));
6972 }
6973 }
6974
6975 function objectIterator() {
6976 if (started < size) {
6977 key = keys[started++];
6978 tasks[key](createCallback(key));
6979 }
6980 }
6981
6982 function createCallback(key) {
6983 return function(err, res) {
6984 if (key === null) {
6985 throwError();
6986 }
6987 if (err) {
6988 key = null;
6989 iterate = noop;
6990 callback = once(callback);
6991 callback(err, result);
6992 return;
6993 }
6994 result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
6995 key = null;
6996 if (++completed === size) {
6997 callback(null, result);
6998 } else if (sync) {
6999 nextTick(iterate);
7000 } else {
7001 sync = true;
7002 iterate();
7003 }
7004 sync = false;
7005 };
7006 }
7007 }
7008
7009 /**
7010 * @memberof async
7011 * @namespace tryEach
7012 * @param {Array|Object} tasks - functions
7013 * @param {Function} callback
7014 * @example
7015 *
7016 * var tasks = [
7017 * function(done) {
7018 * setTimeout(function() {
7019 * done(new Error('error'));
7020 * }, 10);
7021 * },
7022 * function(done) {
7023 * setTimeout(function() {
7024 * done(null, 2);
7025 * }, 10);
7026 * }
7027 * ];
7028 * async.tryEach(tasks, function(err, res) {
7029 * console.log(res); // 2
7030 * });
7031 *
7032 * @example
7033 *
7034 * var tasks = [
7035 * function(done) {
7036 * setTimeout(function() {
7037 * done(new Error('error1'));
7038 * }, 10);
7039 * },
7040 * function(done) {
7041 * setTimeout(function() {
7042 * done(new Error('error2');
7043 * }, 10);
7044 * }
7045 * ];
7046 * async.tryEach(tasks, function(err, res) {
7047 * console.log(err); // error2
7048 * console.log(res); // undefined
7049 * });
7050 *
7051 */
7052 function tryEach(tasks, callback) {
7053 callback = callback || noop;
7054 var size, keys, iterate;
7055 var sync = false;
7056 var completed = 0;
7057
7058 if (isArray(tasks)) {
7059 size = tasks.length;
7060 iterate = arrayIterator;
7061 } else if (tasks && typeof tasks === obj) {
7062 keys = nativeKeys(tasks);
7063 size = keys.length;
7064 iterate = objectIterator;
7065 }
7066 if (!size) {
7067 return callback(null);
7068 }
7069 iterate();
7070
7071 function arrayIterator() {
7072 tasks[completed](done);
7073 }
7074
7075 function objectIterator() {
7076 tasks[keys[completed]](done);
7077 }
7078
7079 function done(err, res) {
7080 if (!err) {
7081 if (arguments.length <= 2) {
7082 callback(null, res);
7083 } else {
7084 callback(null, slice(arguments, 1));
7085 }
7086 } else if (++completed === size) {
7087 callback(err);
7088 } else {
7089 sync = true;
7090 iterate();
7091 }
7092 sync = false;
7093 }
7094 }
7095
7096 /**
7097 * check for waterfall tasks
7098 * @private
7099 * @param {Array} tasks
7100 * @param {Function} callback
7101 * @return {boolean}
7102 */
7103 function checkWaterfallTasks(tasks, callback) {
7104 if (!isArray(tasks)) {
7105 callback(new Error('First argument to waterfall must be an array of functions'));
7106 return false;
7107 }
7108 if (tasks.length === 0) {
7109 callback(null);
7110 return false;
7111 }
7112 return true;
7113 }
7114
7115
7116 /**
7117 * check for waterfall tasks
7118 * @private
7119 * @param {function} func
7120 * @param {Array|Object} args - arguments
7121 * @return {function} next
7122 */
7123 function waterfallIterator(func, args, next) {
7124 switch (args.length) {
7125 case 0:
7126 case 1:
7127 return func(next);
7128 case 2:
7129 return func(args[1], next);
7130 case 3:
7131 return func(args[1], args[2], next);
7132 case 4:
7133 return func(args[1], args[2], args[3], next);
7134 case 5:
7135 return func(args[1], args[2], args[3], args[4], next);
7136 case 6:
7137 return func(args[1], args[2], args[3], args[4], args[5], next);
7138 default:
7139 args = slice(args, 1);
7140 args.push(next);
7141 return func.apply(null, args);
7142 }
7143 }
7144
7145
7146 /**
7147 * @memberof async
7148 * @namespace waterfall
7149 * @param {Array} tasks - functions
7150 * @param {Function} callback
7151 * @example
7152 *
7153 * var order = [];
7154 * var tasks = [
7155 * function(next) {
7156 * setTimeout(function() {
7157 * order.push(1);
7158 * next(null, 1);
7159 * }, 10);
7160 * },
7161 * function(arg1, next) {
7162 * setTimeout(function() {
7163 * order.push(2);
7164 * next(null, 1, 2);
7165 * }, 30);
7166 * },
7167 * function(arg1, arg2, next) {
7168 * setTimeout(function() {
7169 * order.push(3);
7170 * next(null, 3);
7171 * }, 20);
7172 * },
7173 * function(arg1, next) {
7174 * setTimeout(function() {
7175 * order.push(4);
7176 * next(null, 1, 2, 3, 4);
7177 * }, 40);
7178 * }
7179 * ];
7180 * async.waterfall(tasks, function(err, arg1, arg2, arg3, arg4) {
7181 * console.log(arg1, arg2, arg3, arg4); // 1 2 3 4
7182 * });
7183 *
7184 */
7185 function waterfall(tasks, callback) {
7186 callback = callback || noop;
7187 if (!checkWaterfallTasks(tasks, callback)) {
7188 return;
7189 }
7190 var func, args, done, sync;
7191 var completed = 0;
7192 var size = tasks.length;
7193 waterfallIterator(tasks[0], [], createCallback(0));
7194
7195 function iterate() {
7196 waterfallIterator(func, args, createCallback(func));
7197 }
7198
7199 function createCallback(index) {
7200 return function next(err, res) {
7201 if (index === undefined) {
7202 callback = noop;
7203 throwError();
7204 }
7205 index = undefined;
7206 if (err) {
7207 done = callback;
7208 callback = throwError;
7209 done(err);
7210 return;
7211 }
7212 if (++completed === size) {
7213 done = callback;
7214 callback = throwError;
7215 if (arguments.length <= 2) {
7216 done(err, res);
7217 } else {
7218 done.apply(null, createArray(arguments));
7219 }
7220 return;
7221 }
7222 if (sync) {
7223 args = arguments;
7224 func = tasks[completed] || throwError;
7225 nextTick(iterate);
7226 } else {
7227 sync = true;
7228 waterfallIterator(tasks[completed] || throwError, arguments, createCallback(completed));
7229 }
7230 sync = false;
7231 };
7232 }
7233 }
7234
7235 /**
7236 * `angelFall` is like `waterfall` and inject callback to last argument of next task.
7237 *
7238 * @memberof async
7239 * @namespace angelFall
7240 * @param {Array} tasks - functions
7241 * @param {Function} callback
7242 * @example
7243 *
7244 * var order = [];
7245 * var tasks = [
7246 * function(next) {
7247 * setTimeout(function() {
7248 * order.push(1);
7249 * next(null, 1);
7250 * }, 10);
7251 * },
7252 * function(arg1, empty, next) {
7253 * setTimeout(function() {
7254 * order.push(2);
7255 * next(null, 1, 2);
7256 * }, 30);
7257 * },
7258 * function(next) {
7259 * setTimeout(function() {
7260 * order.push(3);
7261 * next(null, 3);
7262 * }, 20);
7263 * },
7264 * function(arg1, empty1, empty2, empty3, next) {
7265 * setTimeout(function() {
7266 * order.push(4);
7267 * next(null, 1, 2, 3, 4);
7268 * }, 40);
7269 * }
7270 * ];
7271 * async.angelFall(tasks, function(err, arg1, arg2, arg3, arg4) {
7272 * console.log(arg1, arg2, arg3, arg4); // 1 2 3 4
7273 * });
7274 *
7275 */
7276 function angelFall(tasks, callback) {
7277 callback = callback || noop;
7278 if (!checkWaterfallTasks(tasks, callback)) {
7279 return;
7280 }
7281 var completed = 0;
7282 var sync = false;
7283 var size = tasks.length;
7284 var func = tasks[completed];
7285 var args = [];
7286 var iterate = function() {
7287 switch (func.length) {
7288 case 0:
7289 try {
7290 next(null, func());
7291 } catch (e) {
7292 next(e);
7293 }
7294 return;
7295 case 1:
7296 return func(next);
7297 case 2:
7298 return func(args[1], next);
7299 case 3:
7300 return func(args[1], args[2], next);
7301 case 4:
7302 return func(args[1], args[2], args[3], next);
7303 case 5:
7304 return func(args[1], args[2], args[3], args[4], next);
7305 default:
7306 args = slice(args, 1);
7307 args[func.length - 1] = next;
7308 return func.apply(null, args);
7309 }
7310 };
7311 iterate();
7312
7313 function next(err, res) {
7314 if (err) {
7315 iterate = throwError;
7316 callback = onlyOnce(callback);
7317 callback(err);
7318 return;
7319 }
7320 if (++completed === size) {
7321 iterate = throwError;
7322 var done = callback;
7323 callback = throwError;
7324 if (arguments.length === 2) {
7325 done(err, res);
7326 } else {
7327 done.apply(null, createArray(arguments));
7328 }
7329 return;
7330 }
7331 func = tasks[completed];
7332 args = arguments;
7333 if (sync) {
7334 nextTick(iterate);
7335 } else {
7336 sync = true;
7337 iterate();
7338 }
7339 sync = false;
7340 }
7341 }
7342
7343 /**
7344 * @memberof async
7345 * @namespace whilst
7346 * @param {Function} test
7347 * @param {Function} iterator
7348 * @param {Function} callback
7349 */
7350 function whilst(test, iterator, callback) {
7351 callback = callback || noop;
7352 var sync = false;
7353 if (test()) {
7354 iterate();
7355 } else {
7356 callback(null);
7357 }
7358
7359 function iterate() {
7360 if (sync) {
7361 nextTick(next);
7362 } else {
7363 sync = true;
7364 iterator(done);
7365 }
7366 sync = false;
7367 }
7368
7369 function next() {
7370 iterator(done);
7371 }
7372
7373 function done(err, arg) {
7374 if (err) {
7375 return callback(err);
7376 }
7377 if (arguments.length <= 2) {
7378 if (test(arg)) {
7379 iterate();
7380 } else {
7381 callback(null, arg);
7382 }
7383 return;
7384 }
7385 arg = slice(arguments, 1);
7386 if (test.apply(null, arg)) {
7387 iterate();
7388 } else {
7389 callback.apply(null, [null].concat(arg));
7390 }
7391 }
7392 }
7393
7394 /**
7395 * @memberof async
7396 * @namespace doWhilst
7397 * @param {Function} iterator
7398 * @param {Function} test
7399 * @param {Function} callback
7400 */
7401 function doWhilst(iterator, test, callback) {
7402 callback = callback || noop;
7403 var sync = false;
7404 next();
7405
7406 function iterate() {
7407 if (sync) {
7408 nextTick(next);
7409 } else {
7410 sync = true;
7411 iterator(done);
7412 }
7413 sync = false;
7414 }
7415
7416 function next() {
7417 iterator(done);
7418 }
7419
7420 function done(err, arg) {
7421 if (err) {
7422 return callback(err);
7423 }
7424 if (arguments.length <= 2) {
7425 if (test(arg)) {
7426 iterate();
7427 } else {
7428 callback(null, arg);
7429 }
7430 return;
7431 }
7432 arg = slice(arguments, 1);
7433 if (test.apply(null, arg)) {
7434 iterate();
7435 } else {
7436 callback.apply(null, [null].concat(arg));
7437 }
7438 }
7439 }
7440
7441 /**
7442 * @memberof async
7443 * @namespace until
7444 * @param {Function} test
7445 * @param {Function} iterator
7446 * @param {Function} callback
7447 */
7448 function until(test, iterator, callback) {
7449 callback = callback || noop;
7450 var sync = false;
7451 if (!test()) {
7452 iterate();
7453 } else {
7454 callback(null);
7455 }
7456
7457 function iterate() {
7458 if (sync) {
7459 nextTick(next);
7460 } else {
7461 sync = true;
7462 iterator(done);
7463 }
7464 sync = false;
7465 }
7466
7467 function next() {
7468 iterator(done);
7469 }
7470
7471 function done(err, arg) {
7472 if (err) {
7473 return callback(err);
7474 }
7475 if (arguments.length <= 2) {
7476 if (!test(arg)) {
7477 iterate();
7478 } else {
7479 callback(null, arg);
7480 }
7481 return;
7482 }
7483 arg = slice(arguments, 1);
7484 if (!test.apply(null, arg)) {
7485 iterate();
7486 } else {
7487 callback.apply(null, [null].concat(arg));
7488 }
7489 }
7490 }
7491
7492 /**
7493 * @memberof async
7494 * @namespace doUntil
7495 * @param {Function} iterator
7496 * @param {Function} test
7497 * @param {Function} callback
7498 */
7499 function doUntil(iterator, test, callback) {
7500 callback = callback || noop;
7501 var sync = false;
7502 next();
7503
7504 function iterate() {
7505 if (sync) {
7506 nextTick(next);
7507 } else {
7508 sync = true;
7509 iterator(done);
7510 }
7511 sync = false;
7512 }
7513
7514 function next() {
7515 iterator(done);
7516 }
7517
7518 function done(err, arg) {
7519 if (err) {
7520 return callback(err);
7521 }
7522 if (arguments.length <= 2) {
7523 if (!test(arg)) {
7524 iterate();
7525 } else {
7526 callback(null, arg);
7527 }
7528 return;
7529 }
7530 arg = slice(arguments, 1);
7531 if (!test.apply(null, arg)) {
7532 iterate();
7533 } else {
7534 callback.apply(null, [null].concat(arg));
7535 }
7536 }
7537 }
7538
7539 /**
7540 * @memberof async
7541 * @namespace during
7542 * @param {Function} test
7543 * @param {Function} iterator
7544 * @param {Function} callback
7545 */
7546 function during(test, iterator, callback) {
7547 callback = callback || noop;
7548 _test();
7549
7550 function _test() {
7551 test(iterate);
7552 }
7553
7554 function iterate(err, truth) {
7555 if (err) {
7556 return callback(err);
7557 }
7558 if (truth) {
7559 iterator(done);
7560 } else {
7561 callback(null);
7562 }
7563 }
7564
7565 function done(err) {
7566 if (err) {
7567 return callback(err);
7568 }
7569 _test();
7570 }
7571 }
7572
7573 /**
7574 * @memberof async
7575 * @namespace doDuring
7576 * @param {Function} test
7577 * @param {Function} iterator
7578 * @param {Function} callback
7579 */
7580 function doDuring(iterator, test, callback) {
7581 callback = callback || noop;
7582 iterate(null, true);
7583
7584 function iterate(err, truth) {
7585 if (err) {
7586 return callback(err);
7587 }
7588 if (truth) {
7589 iterator(done);
7590 } else {
7591 callback(null);
7592 }
7593 }
7594
7595 function done(err, res) {
7596 if (err) {
7597 return callback(err);
7598 }
7599 switch (arguments.length) {
7600 case 0:
7601 case 1:
7602 test(iterate);
7603 break;
7604 case 2:
7605 test(res, iterate);
7606 break;
7607 default:
7608 var args = slice(arguments, 1);
7609 args.push(iterate);
7610 test.apply(null, args);
7611 break;
7612 }
7613 }
7614 }
7615
7616 /**
7617 * @memberof async
7618 * @namespace forever
7619 */
7620 function forever(iterator, callback) {
7621 var sync = false;
7622 iterate();
7623
7624 function iterate() {
7625 iterator(next);
7626 }
7627
7628 function next(err) {
7629 if (err) {
7630 if (callback) {
7631 return callback(err);
7632 }
7633 throw err;
7634 }
7635 if (sync) {
7636 nextTick(iterate);
7637 } else {
7638 sync = true;
7639 iterate();
7640 }
7641 sync = false;
7642 }
7643 }
7644
7645 /**
7646 * @memberof async
7647 * @namespace compose
7648 */
7649 function compose() {
7650 return seq.apply(null, reverse(arguments));
7651 }
7652
7653 /**
7654 * @memberof async
7655 * @namespace seq
7656 */
7657 function seq( /* functions... */ ) {
7658 var fns = createArray(arguments);
7659
7660 return function() {
7661
7662 var self = this;
7663 var args = createArray(arguments);
7664 var callback = args[args.length - 1];
7665 if (typeof callback === func) {
7666 args.pop();
7667 } else {
7668 callback = noop;
7669 }
7670 reduce(fns, args, iterator, done);
7671
7672 function iterator(newargs, fn, callback) {
7673 var func = function(err) {
7674 var nextargs = slice(arguments, 1);
7675 callback(err, nextargs);
7676 };
7677 newargs.push(func);
7678 fn.apply(self, newargs);
7679 }
7680
7681 function done(err, res) {
7682 res = isArray(res) ? res : [res];
7683 res.unshift(err);
7684 callback.apply(self, res);
7685 }
7686 };
7687 }
7688
7689 function createApplyEach(func) {
7690
7691 return function applyEach(fns /* arguments */ ) {
7692
7693 var go = function() {
7694 var self = this;
7695 var args = createArray(arguments);
7696 var callback = args.pop() || noop;
7697 return func(fns, iterator, callback);
7698
7699 function iterator(fn, done) {
7700 fn.apply(self, args.concat([done]));
7701 }
7702 };
7703 if (arguments.length > 1) {
7704 var args = slice(arguments, 1);
7705 return go.apply(this, args);
7706 } else {
7707 return go;
7708 }
7709 };
7710 }
7711
7712 /**
7713 * @see https://github.com/caolan/async/blob/master/lib/internal/DoublyLinkedList.js
7714 */
7715 function DLL() {
7716 this.head = null;
7717 this.tail = null;
7718 this.length = 0;
7719 }
7720
7721 DLL.prototype._removeLink = function(node) {
7722 var prev = node.prev;
7723 var next = node.next;
7724 if (prev) {
7725 prev.next = next;
7726 } else {
7727 this.head = next;
7728 }
7729 if (next) {
7730 next.prev = prev;
7731 } else {
7732 this.tail = prev;
7733 }
7734 node.prev = null;
7735 node.next = null;
7736 this.length--;
7737 return node;
7738 };
7739
7740 DLL.prototype.empty = DLL;
7741
7742 DLL.prototype._setInitial = function(node) {
7743 this.length = 1;
7744 this.head = this.tail = node;
7745 };
7746
7747 DLL.prototype.insertBefore = function(node, newNode) {
7748 newNode.prev = node.prev;
7749 newNode.next = node;
7750 if (node.prev) {
7751 node.prev.next = newNode;
7752 } else {
7753 this.head = newNode;
7754 }
7755 node.prev = newNode;
7756 this.length++;
7757 };
7758
7759 DLL.prototype.unshift = function(node) {
7760 if (this.head) {
7761 this.insertBefore(this.head, node);
7762 } else {
7763 this._setInitial(node);
7764 }
7765 };
7766
7767 DLL.prototype.push = function(node) {
7768 var tail = this.tail;
7769 if (tail) {
7770 node.prev = tail;
7771 node.next = tail.next;
7772 this.tail = node;
7773 tail.next = node;
7774 this.length++;
7775 } else {
7776 this._setInitial(node);
7777 }
7778 };
7779
7780 DLL.prototype.shift = function() {
7781 return this.head && this._removeLink(this.head);
7782 };
7783
7784 DLL.prototype.splice = function(end) {
7785 var task;
7786 var tasks = [];
7787 while (end-- && (task = this.shift())) {
7788 tasks.push(task);
7789 }
7790 return tasks;
7791 };
7792
7793 DLL.prototype.remove = function(test) {
7794 var node = this.head;
7795 while(node) {
7796 if (test(node)) {
7797 this._removeLink(node);
7798 }
7799 node = node.next;
7800 }
7801 return this;
7802 };
7803
7804 /**
7805 * @private
7806 */
7807 function baseQueue(isQueue, worker, concurrency, payload) {
7808 if (concurrency === undefined) {
7809 concurrency = 1;
7810 } else if (isNaN(concurrency) || concurrency < 1) {
7811 throw new Error('Concurrency must not be zero');
7812 }
7813
7814 var workers = 0;
7815 var workersList = [];
7816 var _callback, _unshift;
7817
7818 var q = {
7819 _tasks: new DLL(),
7820 concurrency: concurrency,
7821 payload: payload,
7822 saturated: noop,
7823 unsaturated: noop,
7824 buffer: concurrency / 4,
7825 empty: noop,
7826 drain: noop,
7827 error: noop,
7828 started: false,
7829 paused: false,
7830 push: push,
7831 kill: kill,
7832 unshift: unshift,
7833 remove: remove,
7834 process: isQueue ? runQueue : runCargo,
7835 length: getLength,
7836 running: running,
7837 workersList: getWorkersList,
7838 idle: idle,
7839 pause: pause,
7840 resume: resume,
7841 _worker: worker
7842 };
7843 return q;
7844
7845 function push(tasks, callback) {
7846 _insert(tasks, callback);
7847 }
7848
7849 function unshift(tasks, callback) {
7850 _insert(tasks, callback, true);
7851 }
7852
7853 function _exec(task) {
7854 var item = {
7855 data: task,
7856 callback: _callback
7857 };
7858 if (_unshift) {
7859 q._tasks.unshift(item);
7860 } else {
7861 q._tasks.push(item);
7862 }
7863 nextTick(q.process);
7864 }
7865
7866 function _insert(tasks, callback, unshift) {
7867 if (callback == null) {
7868 callback = noop;
7869 } else if (typeof callback !== 'function') {
7870 throw new Error('task callback must be a function');
7871 }
7872 q.started = true;
7873 var _tasks = isArray(tasks) ? tasks : [tasks];
7874
7875 if (tasks === undefined || !_tasks.length) {
7876 if (q.idle()) {
7877 nextTick(q.drain);
7878 }
7879 return;
7880 }
7881
7882 _unshift = unshift;
7883 _callback = callback;
7884 arrayEachSync(_tasks, _exec);
7885 }
7886
7887 function kill() {
7888 q.drain = noop;
7889 q._tasks.empty();
7890 }
7891
7892 function _next(q, tasks) {
7893 var called = false;
7894 return function done(err, res) {
7895 if (called) {
7896 throwError();
7897 }
7898 called = true;
7899
7900 workers--;
7901 var task;
7902 var index = -1;
7903 var size = workersList.length;
7904 var taskIndex = -1;
7905 var taskSize = tasks.length;
7906 var useApply = arguments.length > 2;
7907 var args = useApply && createArray(arguments);
7908 while (++taskIndex < taskSize) {
7909 task = tasks[taskIndex];
7910 while (++index < size) {
7911 if (workersList[index] === task) {
7912 workersList.splice(index, 1);
7913 index = size;
7914 size--;
7915 }
7916 }
7917 index = -1;
7918 if (useApply) {
7919 task.callback.apply(task, args);
7920 } else {
7921 task.callback(err, res);
7922 }
7923 if (err) {
7924 q.error(err, task.data);
7925 }
7926 }
7927
7928 if (workers <= q.concurrency - q.buffer) {
7929 q.unsaturated();
7930 }
7931
7932 if (q._tasks.length + workers === 0) {
7933 q.drain();
7934 }
7935 q.process();
7936 };
7937 }
7938
7939 function runQueue() {
7940 while (!q.paused && workers < q.concurrency && q._tasks.length) {
7941 var task = q._tasks.shift();
7942 workers++;
7943 workersList.push(task);
7944 if (q._tasks.length === 0) {
7945 q.empty();
7946 }
7947 if (workers === q.concurrency) {
7948 q.saturated();
7949 }
7950 var done = _next(q, [task]);
7951 worker(task.data, done);
7952 }
7953 }
7954
7955 function runCargo() {
7956 while (!q.paused && workers < q.concurrency && q._tasks.length) {
7957 var tasks = q._tasks.splice(q.payload || q._tasks.length);
7958 var index = -1;
7959 var size = tasks.length;
7960 var data = Array(size);
7961 while (++index < size) {
7962 data[index] = tasks[index].data;
7963 }
7964 workers++;
7965 nativePush.apply(workersList, tasks);
7966 if (q._tasks.length === 0) {
7967 q.empty();
7968 }
7969 if (workers === q.concurrency) {
7970 q.saturated();
7971 }
7972 var done = _next(q, tasks);
7973 worker(data, done);
7974 }
7975 }
7976
7977 function getLength() {
7978 return q._tasks.length;
7979 }
7980
7981 function running() {
7982 return workers;
7983 }
7984
7985 function getWorkersList() {
7986 return workersList;
7987 }
7988
7989 function idle() {
7990 return q.length() + workers === 0;
7991 }
7992
7993 function pause() {
7994 q.paused = true;
7995 }
7996
7997 function _resume() {
7998 nextTick(q.process);
7999 }
8000
8001 function resume() {
8002 if (q.paused === false) {
8003 return;
8004 }
8005 q.paused = false;
8006 var count = q.concurrency < q._tasks.length ? q.concurrency : q._tasks.length;
8007 timesSync(count, _resume);
8008 }
8009
8010 /**
8011 * @param {Function} test
8012 */
8013 function remove(test) {
8014 q._tasks.remove(test);
8015 }
8016 }
8017
8018 /**
8019 * @memberof async
8020 * @namespace queue
8021 */
8022 function queue(worker, concurrency) {
8023 return baseQueue(true, worker, concurrency);
8024 }
8025
8026 /**
8027 * @memberof async
8028 * @namespace priorityQueue
8029 */
8030 function priorityQueue(worker, concurrency) {
8031 var q = baseQueue(true, worker, concurrency);
8032 q.push = push;
8033 delete q.unshift;
8034 return q;
8035
8036 function push(tasks, priority, callback) {
8037 q.started = true;
8038 priority = priority || 0;
8039 var _tasks = isArray(tasks) ? tasks : [tasks];
8040 var taskSize = _tasks.length;
8041
8042 if (tasks === undefined || taskSize === 0) {
8043 if (q.idle()) {
8044 nextTick(q.drain);
8045 }
8046 return;
8047 }
8048
8049 callback = typeof callback === func ? callback : noop;
8050 var nextNode = q._tasks.head;
8051 while (nextNode && priority >= nextNode.priority) {
8052 nextNode = nextNode.next;
8053 }
8054 while (taskSize--) {
8055 var item = {
8056 data: _tasks[taskSize],
8057 priority: priority,
8058 callback: callback
8059 };
8060 if (nextNode) {
8061 q._tasks.insertBefore(nextNode, item);
8062 } else {
8063 q._tasks.push(item);
8064 }
8065 nextTick(q.process);
8066 }
8067 }
8068 }
8069
8070 /**
8071 * @memberof async
8072 * @namespace cargo
8073 */
8074 function cargo(worker, payload) {
8075 return baseQueue(false, worker, 1, payload);
8076 }
8077
8078 /**
8079 * @memberof async
8080 * @namespace auto
8081 * @param {Object} tasks
8082 * @param {number} [concurrency]
8083 * @param {Function} [callback]
8084 */
8085 function auto(tasks, concurrency, callback) {
8086 if (typeof concurrency === func) {
8087 callback = concurrency;
8088 concurrency = null;
8089 }
8090 var keys = nativeKeys(tasks);
8091 var rest = keys.length;
8092 var results = {};
8093 if (rest === 0) {
8094 return callback(null, results);
8095 }
8096 var runningTasks = 0;
8097 var readyTasks = [];
8098 var listeners = Object.create(null);
8099 callback = onlyOnce(callback || noop);
8100 concurrency = concurrency || rest;
8101
8102 baseEachSync(tasks, iterator, keys);
8103 proceedQueue();
8104
8105 function iterator(task, key) {
8106 // no dependencies
8107 var _task, _taskSize;
8108 if (!isArray(task)) {
8109 _task = task;
8110 _taskSize = 0;
8111 readyTasks.push([_task, _taskSize, done]);
8112 return;
8113 }
8114 var dependencySize = task.length - 1;
8115 _task = task[dependencySize];
8116 _taskSize = dependencySize;
8117 if (dependencySize === 0) {
8118 readyTasks.push([_task, _taskSize, done]);
8119 return;
8120 }
8121 // dependencies
8122 var index = -1;
8123 while (++index < dependencySize) {
8124 var dependencyName = task[index];
8125 if (notInclude(keys, dependencyName)) {
8126 var msg = 'async.auto task `' + key + '` has non-existent dependency `' + dependencyName + '` in ' + task.join(', ');
8127 throw new Error(msg);
8128 }
8129 var taskListeners = listeners[dependencyName];
8130 if (!taskListeners) {
8131 taskListeners = listeners[dependencyName] = [];
8132 }
8133 taskListeners.push(taskListener);
8134 }
8135
8136 function done(err, arg) {
8137 if (key === null) {
8138 throwError();
8139 }
8140 runningTasks--;
8141 rest--;
8142 arg = arguments.length <= 2 ? arg : slice(arguments, 1);
8143 if (err) {
8144 var safeResults = objectClone(results);
8145 safeResults[key] = arg;
8146 key = null;
8147 var _callback = callback;
8148 callback = noop;
8149 _callback(err, safeResults);
8150 return;
8151 }
8152 results[key] = arg;
8153 taskComplete(key);
8154 key = null;
8155 }
8156
8157 function taskListener() {
8158 if (--dependencySize === 0) {
8159 readyTasks.push([_task, _taskSize, done]);
8160 }
8161 }
8162 }
8163
8164 function proceedQueue() {
8165 if (readyTasks.length === 0 && runningTasks === 0) {
8166 if (rest !== 0) {
8167 throw new Error('async.auto task has cyclic dependencies');
8168 }
8169 return callback(null, results);
8170 }
8171 while (readyTasks.length && runningTasks < concurrency && callback !== noop) {
8172 runningTasks++;
8173 var array = readyTasks.shift();
8174 if (array[1] === 0) {
8175 array[0](array[2]);
8176 } else {
8177 array[0](results, array[2]);
8178 }
8179 }
8180 }
8181
8182 function taskComplete(key) {
8183 var taskListeners = listeners[key] || [];
8184 arrayEachSync(taskListeners, function(task) {
8185 task();
8186 });
8187 proceedQueue();
8188 }
8189 }
8190
8191 var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
8192 var FN_ARG_SPLIT = /,/;
8193 var FN_ARG = /(=.+)?(\s*)$/;
8194 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
8195
8196 /**
8197 * parse function arguments for `autoInject`
8198 *
8199 * @private
8200 */
8201 function parseParams(func) {
8202 func = func.toString().replace(STRIP_COMMENTS, '');
8203 func = func.match(FN_ARGS)[2].replace(' ', '');
8204 func = func ? func.split(FN_ARG_SPLIT) : [];
8205 func = func.map(function (arg) {
8206 return arg.replace(FN_ARG, '').trim();
8207 });
8208 return func;
8209 }
8210
8211 /**
8212 * @memberof async
8213 * @namespace autoInject
8214 * @param {Object} tasks
8215 * @param {number} [concurrency]
8216 * @param {Function} [callback]
8217 */
8218 function autoInject(tasks, concurrency, callback) {
8219 var newTasks = {};
8220 baseEachSync(tasks, iterator, nativeKeys(tasks));
8221 auto(newTasks, concurrency, callback);
8222
8223 function iterator(task, key) {
8224 var params;
8225 var taskLength = task.length;
8226
8227 if (isArray(task)) {
8228 if (taskLength === 0) {
8229 throw new Error('autoInject task functions require explicit parameters.');
8230 }
8231 params = createArray(task);
8232 taskLength = params.length - 1;
8233 task = params[taskLength];
8234 if (taskLength === 0) {
8235 newTasks[key] = task;
8236 return;
8237 }
8238 } else if (taskLength === 1) {
8239 newTasks[key] = task;
8240 return;
8241 } else {
8242 params = parseParams(task);
8243 if (taskLength === 0 && params.length === 0) {
8244 throw new Error('autoInject task functions require explicit parameters.');
8245 }
8246 taskLength = params.length - 1;
8247 }
8248 params[taskLength] = newTask;
8249 newTasks[key] = params;
8250
8251 function newTask(results, done) {
8252 switch (taskLength) {
8253 case 1:
8254 task(results[params[0]], done);
8255 break;
8256 case 2:
8257 task(results[params[0]], results[params[1]], done);
8258 break;
8259 case 3:
8260 task(results[params[0]], results[params[1]], results[params[2]], done);
8261 break;
8262 default:
8263 var i = -1;
8264 while(++i < taskLength) {
8265 params[i] = results[params[i]];
8266 }
8267 params[i] = done;
8268 task.apply(null, params);
8269 break;
8270 }
8271 }
8272 }
8273 }
8274
8275 /**
8276 * @memberof async
8277 * @namespace retry
8278 * @param {integer|Object|Function} opts
8279 * @param {Function} [task]
8280 * @param {Function} [callback]
8281 */
8282 function retry(opts, task, callback) {
8283 var times, intervalFunc, errorFilter;
8284 var count = 0;
8285 if (arguments.length < 3 && typeof opts === func) {
8286 callback = task || noop;
8287 task = opts;
8288 opts = null;
8289 times = DEFAULT_TIMES;
8290 } else {
8291 callback = callback || noop;
8292 switch (typeof opts) {
8293 case 'object':
8294 if (typeof opts.errorFilter === func) {
8295 errorFilter = opts.errorFilter;
8296 }
8297 var interval = opts.interval;
8298 switch (typeof interval) {
8299 case func:
8300 intervalFunc = interval;
8301 break;
8302 case 'string':
8303 case 'number':
8304 interval = +interval;
8305 intervalFunc = interval ? function() {
8306 return interval;
8307 } : function() {
8308 return DEFAULT_INTERVAL;
8309 };
8310 break;
8311 }
8312 times = +opts.times || DEFAULT_TIMES;
8313 break;
8314 case 'number':
8315 times = opts || DEFAULT_TIMES;
8316 break;
8317 case 'string':
8318 times = +opts || DEFAULT_TIMES;
8319 break;
8320 default:
8321 throw new Error('Invalid arguments for async.retry');
8322 }
8323 }
8324 if (typeof task !== 'function') {
8325 throw new Error('Invalid arguments for async.retry');
8326 }
8327
8328 if (intervalFunc) {
8329 task(intervalCallback);
8330 } else {
8331 task(simpleCallback);
8332 }
8333
8334 function simpleIterator() {
8335 task(simpleCallback);
8336 }
8337
8338 function simpleCallback(err, res) {
8339 if (++count === times || !err || errorFilter && !errorFilter(err)) {
8340 if (arguments.length <= 2) {
8341 return callback(err, res);
8342 }
8343 var args = createArray(arguments);
8344 return callback.apply(null, args);
8345 }
8346 simpleIterator();
8347 }
8348
8349 function intervalIterator() {
8350 task(intervalCallback);
8351 }
8352
8353 function intervalCallback(err, res) {
8354 if (++count === times || !err || errorFilter && !errorFilter(err)) {
8355 if (arguments.length <= 2) {
8356 return callback(err, res);
8357 }
8358 var args = createArray(arguments);
8359 return callback.apply(null, args);
8360 }
8361 setTimeout(intervalIterator, intervalFunc(count));
8362 }
8363 }
8364
8365 function retryable(opts, task) {
8366 if (!task) {
8367 task = opts;
8368 opts = null;
8369 }
8370 return done;
8371
8372 function done() {
8373 var taskFn;
8374 var args = createArray(arguments);
8375 var lastIndex = args.length - 1;
8376 var callback = args[lastIndex];
8377 switch (task.length) {
8378 case 1:
8379 taskFn = task1;
8380 break;
8381 case 2:
8382 taskFn = task2;
8383 break;
8384 case 3:
8385 taskFn = task3;
8386 break;
8387 default:
8388 taskFn = task4;
8389 }
8390 if (opts) {
8391 retry(opts, taskFn, callback);
8392 } else {
8393 retry(taskFn, callback);
8394 }
8395
8396 function task1(done) {
8397 task(done);
8398 }
8399
8400 function task2(done) {
8401 task(args[0], done);
8402 }
8403
8404 function task3(done) {
8405 task(args[0], args[1], done);
8406 }
8407
8408 function task4(callback) {
8409 args[lastIndex] = callback;
8410 task.apply(null, args);
8411 }
8412 }
8413 }
8414
8415 /**
8416 * @memberof async
8417 * @namespace iterator
8418 */
8419 function iterator(tasks) {
8420 var size = 0;
8421 var keys = [];
8422 if (isArray(tasks)) {
8423 size = tasks.length;
8424 } else {
8425 keys = nativeKeys(tasks);
8426 size = keys.length;
8427 }
8428 return makeCallback(0);
8429
8430 function makeCallback(index) {
8431 var fn = function() {
8432 if (size) {
8433 var key = keys[index] || index;
8434 tasks[key].apply(null, createArray(arguments));
8435 }
8436 return fn.next();
8437 };
8438 fn.next = function() {
8439 return (index < size - 1) ? makeCallback(index + 1) : null;
8440 };
8441 return fn;
8442 }
8443 }
8444
8445 /**
8446 * @memberof async
8447 * @namespace apply
8448 */
8449 function apply(func) {
8450 switch (arguments.length) {
8451 case 0:
8452 case 1:
8453 return func;
8454 case 2:
8455 return func.bind(null, arguments[1]);
8456 case 3:
8457 return func.bind(null, arguments[1], arguments[2]);
8458 case 4:
8459 return func.bind(null, arguments[1], arguments[2], arguments[3]);
8460 case 5:
8461 return func.bind(null, arguments[1], arguments[2], arguments[3], arguments[4]);
8462 default:
8463 var size = arguments.length;
8464 var index = 0;
8465 var args = Array(size);
8466 args[index] = null;
8467 while (++index < size) {
8468 args[index] = arguments[index];
8469 }
8470 return func.bind.apply(func, args);
8471 }
8472 }
8473
8474 /**
8475 * @memberof async
8476 * @namespace timeout
8477 * @param {Function} func
8478 * @param {number} millisec
8479 * @param {*} info
8480 */
8481 function timeout(func, millisec, info) {
8482 var callback, timer;
8483 return wrappedFunc;
8484
8485 function wrappedFunc() {
8486 timer = setTimeout(timeoutCallback, millisec);
8487 var args = createArray(arguments);
8488 var lastIndex = args.length - 1;
8489 callback = args[lastIndex];
8490 args[lastIndex] = injectedCallback;
8491 simpleApply(func, args);
8492 }
8493
8494 function timeoutCallback() {
8495 var name = func.name || 'anonymous';
8496 var err = new Error('Callback function "' + name + '" timed out.');
8497 err.code = 'ETIMEDOUT';
8498 if (info) {
8499 err.info = info;
8500 }
8501 timer = null;
8502 callback(err);
8503 }
8504
8505 function injectedCallback() {
8506 if (timer !== null) {
8507 simpleApply(callback, createArray(arguments));
8508 clearTimeout(timer);
8509 }
8510 }
8511
8512 function simpleApply(func, args) {
8513 switch(args.length) {
8514 case 0:
8515 func();
8516 break;
8517 case 1:
8518 func(args[0]);
8519 break;
8520 case 2:
8521 func(args[0], args[1]);
8522 break;
8523 default:
8524 func.apply(null, args);
8525 break;
8526 }
8527 }
8528 }
8529
8530 /**
8531 * @memberof async
8532 * @namespace times
8533 * @param {number} n - n >= 1
8534 * @param {Function} iterator
8535 * @param {Function} callback
8536 * @example
8537 *
8538 * var iterator = function(n, done) {
8539 * done(null, n);
8540 * };
8541 * async.times(4, iterator, function(err, res) {
8542 * console.log(res); // [0, 1, 2, 3];
8543 * });
8544 *
8545 */
8546 function times(n, iterator, callback) {
8547 callback = callback || noop;
8548 n = +n;
8549 if (isNaN(n) || n < 1) {
8550 return callback(null, []);
8551 }
8552 var result = Array(n);
8553 timesSync(n, iterate);
8554
8555 function iterate(num) {
8556 iterator(num, createCallback(num));
8557 }
8558
8559 function createCallback(index) {
8560 return function(err, res) {
8561 if (index === null) {
8562 throwError();
8563 }
8564 result[index] = res;
8565 index = null;
8566 if (err) {
8567 callback(err);
8568 callback = noop;
8569 } else if (--n === 0) {
8570 callback(null, result);
8571 }
8572 };
8573 }
8574 }
8575
8576 /**
8577 * @memberof async
8578 * @namespace timesSeries
8579 * @param {number} n - n >= 1
8580 * @param {Function} iterator
8581 * @param {Function} callback
8582 * @example
8583 *
8584 * var iterator = function(n, done) {
8585 * done(null, n);
8586 * };
8587 * async.timesSeries(4, iterator, function(err, res) {
8588 * console.log(res); // [0, 1, 2, 3];
8589 * });
8590 *
8591 */
8592 function timesSeries(n, iterator, callback) {
8593 callback = callback || noop;
8594 n = +n;
8595 if (isNaN(n) || n < 1) {
8596 return callback(null, []);
8597 }
8598 var result = Array(n);
8599 var sync = false;
8600 var completed = 0;
8601 iterate();
8602
8603 function iterate() {
8604 iterator(completed, done);
8605 }
8606
8607 function done(err, res) {
8608 result[completed] = res;
8609 if (err) {
8610 callback(err);
8611 callback = throwError;
8612 } else if (++completed >= n) {
8613 callback(null, result);
8614 callback = throwError;
8615 } else if (sync) {
8616 nextTick(iterate);
8617 } else {
8618 sync = true;
8619 iterate();
8620 }
8621 sync = false;
8622 }
8623 }
8624
8625 /**
8626 * @memberof async
8627 * @namespace timesLimit
8628 * @param {number} n - n >= 1
8629 * @param {number} limit - n >= 1
8630 * @param {Function} iterator
8631 * @param {Function} callback
8632 * @example
8633 *
8634 * var iterator = function(n, done) {
8635 * done(null, n);
8636 * };
8637 * async.timesLimit(4, 2, iterator, function(err, res) {
8638 * console.log(res); // [0, 1, 2, 3];
8639 * });
8640 *
8641 */
8642 function timesLimit(n, limit, iterator, callback) {
8643 callback = callback || noop;
8644 n = +n;
8645 if (isNaN(n) || n < 1 || isNaN(limit) || limit < 1) {
8646 return callback(null, []);
8647 }
8648 var result = Array(n);
8649 var sync = false;
8650 var started = 0;
8651 var completed = 0;
8652 timesSync(limit > n ? n : limit, iterate);
8653
8654 function iterate() {
8655 var index = started++;
8656 if (index < n) {
8657 iterator(index, createCallback(index));
8658 }
8659 }
8660
8661 function createCallback(index) {
8662 return function(err, res) {
8663 if (index === null) {
8664 throwError();
8665 }
8666 result[index] = res;
8667 index = null;
8668 if (err) {
8669 callback(err);
8670 callback = noop;
8671 } else if (++completed >= n) {
8672 callback(null, result);
8673 callback = throwError;
8674 } else if (sync) {
8675 nextTick(iterate);
8676 } else {
8677 sync = true;
8678 iterate();
8679 }
8680 sync = false;
8681 };
8682 }
8683 }
8684
8685 /**
8686 * @memberof async
8687 * @namespace race
8688 * @param {Array|Object} tasks - functions
8689 * @param {Function} callback
8690 * @example
8691 *
8692 * // array
8693 * var called = 0;
8694 * var tasks = [
8695 * function(done) {
8696 * setTimeout(function() {
8697 * called++;
8698 * done(null, '1');
8699 * }, 30);
8700 * },
8701 * function(done) {
8702 * setTimeout(function() {
8703 * called++;
8704 * done(null, '2');
8705 * }, 20);
8706 * },
8707 * function(done) {
8708 * setTimeout(function() {
8709 * called++;
8710 * done(null, '3');
8711 * }, 10);
8712 * }
8713 * ];
8714 * async.race(tasks, function(err, res) {
8715 * console.log(res); // '3'
8716 * console.log(called); // 1
8717 * setTimeout(function() {
8718 * console.log(called); // 3
8719 * }, 50);
8720 * });
8721 *
8722 * @example
8723 *
8724 * // object
8725 * var called = 0;
8726 * var tasks = {
8727 * 'test1': function(done) {
8728 * setTimeout(function() {
8729 * called++;
8730 * done(null, '1');
8731 * }, 30);
8732 * },
8733 * 'test2': function(done) {
8734 * setTimeout(function() {
8735 * called++;
8736 * done(null, '2');
8737 * }, 20);
8738 * },
8739 * 'test3': function(done) {
8740 * setTimeout(function() {
8741 * called++;
8742 * done(null, '3');
8743 * }, 10);
8744 * }
8745 * };
8746 * async.race(tasks, function(err, res) {
8747 * console.log(res); // '3'
8748 * console.log(called); // 1
8749 * setTimeout(function() {
8750 * console.log(called); // 3
8751 * done();
8752 * }, 50);
8753 * });
8754 *
8755 */
8756 function race(tasks, callback) {
8757 callback = once(callback || noop);
8758 var size, keys;
8759 var index = -1;
8760 if (isArray(tasks)) {
8761 size = tasks.length;
8762 while (++index < size) {
8763 tasks[index](callback);
8764 }
8765 } else if (tasks && typeof tasks === obj) {
8766 keys = nativeKeys(tasks);
8767 size = keys.length;
8768 while (++index < size) {
8769 tasks[keys[index]](callback);
8770 }
8771 } else {
8772 return callback(new TypeError('First argument to race must be a collection of functions'));
8773 }
8774 if (!size) {
8775 callback(null);
8776 }
8777 }
8778
8779 /**
8780 * @memberof async
8781 * @namespace memoize
8782 */
8783 function memoize(fn, hasher) {
8784 hasher = hasher || function(hash) {
8785 return hash;
8786 };
8787
8788 var memo = {};
8789 var queues = {};
8790 var memoized = function() {
8791 var args = createArray(arguments);
8792 var callback = args.pop();
8793 var key = hasher.apply(null, args);
8794 if (has(memo, key)) {
8795 nextTick(function() {
8796 callback.apply(null, memo[key]);
8797 });
8798 return;
8799 }
8800 if (has(queues, key)) {
8801 return queues[key].push(callback);
8802 }
8803
8804 queues[key] = [callback];
8805 args.push(done);
8806 fn.apply(null, args);
8807
8808 function done() {
8809 var args = createArray(arguments);
8810 memo[key] = args;
8811 var q = queues[key];
8812 delete queues[key];
8813
8814 var i = -1;
8815 var size = q.length;
8816 while (++i < size) {
8817 q[i].apply(null, args);
8818 }
8819 }
8820 };
8821 memoized.memo = memo;
8822 memoized.unmemoized = fn;
8823 return memoized;
8824 }
8825
8826 /**
8827 * @memberof async
8828 * @namespace unmemoize
8829 */
8830 function unmemoize(fn) {
8831 return function() {
8832 return (fn.unmemoized || fn).apply(null, arguments);
8833 };
8834 }
8835
8836 /**
8837 * @memberof async
8838 * @namespace ensureAsync
8839 */
8840 function ensureAsync(fn) {
8841 return function( /* ...args, callback */ ) {
8842 var args = createArray(arguments);
8843 var lastIndex = args.length - 1;
8844 var callback = args[lastIndex];
8845 var sync = true;
8846 args[lastIndex] = done;
8847 fn.apply(this, args);
8848 sync = false;
8849
8850 function done() {
8851 var innerArgs = createArray(arguments);
8852 if (sync) {
8853 nextTick(function() {
8854 callback.apply(null, innerArgs);
8855 });
8856 } else {
8857 callback.apply(null, innerArgs);
8858 }
8859 }
8860 };
8861 }
8862
8863 /**
8864 * @memberof async
8865 * @namespace constant
8866 */
8867 function constant( /* values... */ ) {
8868 var args = [null].concat(createArray(arguments));
8869 return function(callback) {
8870 callback = arguments[arguments.length - 1];
8871 callback.apply(this, args);
8872 };
8873 }
8874
8875 function asyncify(fn) {
8876 return function( /* args..., callback */ ) {
8877 var args = createArray(arguments);
8878 var callback = args.pop();
8879 var result;
8880 try {
8881 result = fn.apply(this, args);
8882 } catch (e) {
8883 return callback(e);
8884 }
8885 if (result && typeof result.then === func) {
8886 result.then(function(value) {
8887 invokeCallback(callback, null, value);
8888 }, function(err) {
8889 invokeCallback(callback, err.message ? err : new Error(err));
8890 });
8891 } else {
8892 callback(null, result);
8893 }
8894 };
8895 }
8896
8897 function invokeCallback(callback, err, value) {
8898 try {
8899 callback(err, value);
8900 } catch (e) {
8901 nextTick(rethrow, e);
8902 }
8903 }
8904
8905 function rethrow(error) {
8906 throw error;
8907 }
8908
8909 /**
8910 * @memberof async
8911 * @namespace reflect
8912 * @param {Function} func
8913 * @return {Function}
8914 */
8915 function reflect(func) {
8916 return function( /* args..., callback */ ) {
8917 var callback;
8918 switch (arguments.length) {
8919 case 1:
8920 callback = arguments[0];
8921 return func(done);
8922 case 2:
8923 callback = arguments[1];
8924 return func(arguments[0], done);
8925 default:
8926 var args = createArray(arguments);
8927 var lastIndex = args.length - 1;
8928 callback = args[lastIndex];
8929 args[lastIndex] = done;
8930 func.apply(this, args);
8931 }
8932
8933 function done(err, res) {
8934 if (err) {
8935 return callback(null, {
8936 error: err
8937 });
8938 }
8939 if (arguments.length > 2) {
8940 res = slice(arguments, 1);
8941 }
8942 callback(null, {
8943 value: res
8944 });
8945 }
8946 };
8947 }
8948
8949 /**
8950 * @memberof async
8951 * @namespace reflectAll
8952 * @param {Array[]|Object} tasks
8953 * @return {Function}
8954 */
8955 function reflectAll(tasks) {
8956 var size, newTasks, keys;
8957 if (isArray(tasks)) {
8958 size = tasks.length;
8959 newTasks = Array(size);
8960 arrayEachSync(tasks, iterate);
8961 } else if (tasks && typeof tasks === obj) {
8962 keys = nativeKeys(tasks);
8963 size = keys.length;
8964 newTasks = {};
8965 baseEachSync(tasks, iterate, keys);
8966 }
8967 return newTasks;
8968
8969 function iterate(func, key) {
8970 newTasks[key] = reflect(func);
8971 }
8972 }
8973
8974 /**
8975 * @memberof async
8976 * @namespace createLogger
8977 */
8978 function createLogger(name) {
8979 return function(fn) {
8980 var args = slice(arguments, 1);
8981 args.push(done);
8982 fn.apply(null, args);
8983 };
8984
8985 function done(err) {
8986 if (typeof console === obj) {
8987 if (err) {
8988 if (console.error) {
8989 console.error(err);
8990 }
8991 return;
8992 }
8993 if (console[name]) {
8994 var args = slice(arguments, 1);
8995 arrayEachSync(args, function(arg) {
8996 console[name](arg);
8997 });
8998 }
8999 }
9000 }
9001 }
9002
9003 /**
9004 * @memberof async
9005 * @namespace safe
9006 */
9007 function safe() {
9008 createImmediate();
9009 return exports;
9010 }
9011
9012 /**
9013 * @memberof async
9014 * @namespace fast
9015 */
9016 function fast() {
9017 createImmediate(false);
9018 return exports;
9019 }
9020
9021}));