UNPKG

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