source: trip-planner-front/node_modules/async/dist/async.js@ 188ee53

Last change on this file since 188ee53 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 180.6 KB
RevLine 
[6a3a178]1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (factory((global.async = global.async || {})));
5}(this, (function (exports) { 'use strict';
6
7function slice(arrayLike, start) {
8 start = start|0;
9 var newLen = Math.max(arrayLike.length - start, 0);
10 var newArr = Array(newLen);
11 for(var idx = 0; idx < newLen; idx++) {
12 newArr[idx] = arrayLike[start + idx];
13 }
14 return newArr;
15}
16
17/**
18 * Creates a continuation function with some arguments already applied.
19 *
20 * Useful as a shorthand when combined with other control flow functions. Any
21 * arguments passed to the returned function are added to the arguments
22 * originally passed to apply.
23 *
24 * @name apply
25 * @static
26 * @memberOf module:Utils
27 * @method
28 * @category Util
29 * @param {Function} fn - The function you want to eventually apply all
30 * arguments to. Invokes with (arguments...).
31 * @param {...*} arguments... - Any number of arguments to automatically apply
32 * when the continuation is called.
33 * @returns {Function} the partially-applied function
34 * @example
35 *
36 * // using apply
37 * async.parallel([
38 * async.apply(fs.writeFile, 'testfile1', 'test1'),
39 * async.apply(fs.writeFile, 'testfile2', 'test2')
40 * ]);
41 *
42 *
43 * // the same process without using apply
44 * async.parallel([
45 * function(callback) {
46 * fs.writeFile('testfile1', 'test1', callback);
47 * },
48 * function(callback) {
49 * fs.writeFile('testfile2', 'test2', callback);
50 * }
51 * ]);
52 *
53 * // It's possible to pass any number of additional arguments when calling the
54 * // continuation:
55 *
56 * node> var fn = async.apply(sys.puts, 'one');
57 * node> fn('two', 'three');
58 * one
59 * two
60 * three
61 */
62var apply = function(fn/*, ...args*/) {
63 var args = slice(arguments, 1);
64 return function(/*callArgs*/) {
65 var callArgs = slice(arguments);
66 return fn.apply(null, args.concat(callArgs));
67 };
68};
69
70var initialParams = function (fn) {
71 return function (/*...args, callback*/) {
72 var args = slice(arguments);
73 var callback = args.pop();
74 fn.call(this, args, callback);
75 };
76};
77
78/**
79 * Checks if `value` is the
80 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
81 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
82 *
83 * @static
84 * @memberOf _
85 * @since 0.1.0
86 * @category Lang
87 * @param {*} value The value to check.
88 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
89 * @example
90 *
91 * _.isObject({});
92 * // => true
93 *
94 * _.isObject([1, 2, 3]);
95 * // => true
96 *
97 * _.isObject(_.noop);
98 * // => true
99 *
100 * _.isObject(null);
101 * // => false
102 */
103function isObject(value) {
104 var type = typeof value;
105 return value != null && (type == 'object' || type == 'function');
106}
107
108var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
109var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
110
111function fallback(fn) {
112 setTimeout(fn, 0);
113}
114
115function wrap(defer) {
116 return function (fn/*, ...args*/) {
117 var args = slice(arguments, 1);
118 defer(function () {
119 fn.apply(null, args);
120 });
121 };
122}
123
124var _defer;
125
126if (hasSetImmediate) {
127 _defer = setImmediate;
128} else if (hasNextTick) {
129 _defer = process.nextTick;
130} else {
131 _defer = fallback;
132}
133
134var setImmediate$1 = wrap(_defer);
135
136/**
137 * Take a sync function and make it async, passing its return value to a
138 * callback. This is useful for plugging sync functions into a waterfall,
139 * series, or other async functions. Any arguments passed to the generated
140 * function will be passed to the wrapped function (except for the final
141 * callback argument). Errors thrown will be passed to the callback.
142 *
143 * If the function passed to `asyncify` returns a Promise, that promises's
144 * resolved/rejected state will be used to call the callback, rather than simply
145 * the synchronous return value.
146 *
147 * This also means you can asyncify ES2017 `async` functions.
148 *
149 * @name asyncify
150 * @static
151 * @memberOf module:Utils
152 * @method
153 * @alias wrapSync
154 * @category Util
155 * @param {Function} func - The synchronous function, or Promise-returning
156 * function to convert to an {@link AsyncFunction}.
157 * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
158 * invoked with `(args..., callback)`.
159 * @example
160 *
161 * // passing a regular synchronous function
162 * async.waterfall([
163 * async.apply(fs.readFile, filename, "utf8"),
164 * async.asyncify(JSON.parse),
165 * function (data, next) {
166 * // data is the result of parsing the text.
167 * // If there was a parsing error, it would have been caught.
168 * }
169 * ], callback);
170 *
171 * // passing a function returning a promise
172 * async.waterfall([
173 * async.apply(fs.readFile, filename, "utf8"),
174 * async.asyncify(function (contents) {
175 * return db.model.create(contents);
176 * }),
177 * function (model, next) {
178 * // `model` is the instantiated model object.
179 * // If there was an error, this function would be skipped.
180 * }
181 * ], callback);
182 *
183 * // es2017 example, though `asyncify` is not needed if your JS environment
184 * // supports async functions out of the box
185 * var q = async.queue(async.asyncify(async function(file) {
186 * var intermediateStep = await processFile(file);
187 * return await somePromise(intermediateStep)
188 * }));
189 *
190 * q.push(files);
191 */
192function asyncify(func) {
193 return initialParams(function (args, callback) {
194 var result;
195 try {
196 result = func.apply(this, args);
197 } catch (e) {
198 return callback(e);
199 }
200 // if result is Promise object
201 if (isObject(result) && typeof result.then === 'function') {
202 result.then(function(value) {
203 invokeCallback(callback, null, value);
204 }, function(err) {
205 invokeCallback(callback, err.message ? err : new Error(err));
206 });
207 } else {
208 callback(null, result);
209 }
210 });
211}
212
213function invokeCallback(callback, error, value) {
214 try {
215 callback(error, value);
216 } catch (e) {
217 setImmediate$1(rethrow, e);
218 }
219}
220
221function rethrow(error) {
222 throw error;
223}
224
225var supportsSymbol = typeof Symbol === 'function';
226
227function isAsync(fn) {
228 return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction';
229}
230
231function wrapAsync(asyncFn) {
232 return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
233}
234
235function applyEach$1(eachfn) {
236 return function(fns/*, ...args*/) {
237 var args = slice(arguments, 1);
238 var go = initialParams(function(args, callback) {
239 var that = this;
240 return eachfn(fns, function (fn, cb) {
241 wrapAsync(fn).apply(that, args.concat(cb));
242 }, callback);
243 });
244 if (args.length) {
245 return go.apply(this, args);
246 }
247 else {
248 return go;
249 }
250 };
251}
252
253/** Detect free variable `global` from Node.js. */
254var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
255
256/** Detect free variable `self`. */
257var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
258
259/** Used as a reference to the global object. */
260var root = freeGlobal || freeSelf || Function('return this')();
261
262/** Built-in value references. */
263var Symbol$1 = root.Symbol;
264
265/** Used for built-in method references. */
266var objectProto = Object.prototype;
267
268/** Used to check objects for own properties. */
269var hasOwnProperty = objectProto.hasOwnProperty;
270
271/**
272 * Used to resolve the
273 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
274 * of values.
275 */
276var nativeObjectToString = objectProto.toString;
277
278/** Built-in value references. */
279var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
280
281/**
282 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
283 *
284 * @private
285 * @param {*} value The value to query.
286 * @returns {string} Returns the raw `toStringTag`.
287 */
288function getRawTag(value) {
289 var isOwn = hasOwnProperty.call(value, symToStringTag$1),
290 tag = value[symToStringTag$1];
291
292 try {
293 value[symToStringTag$1] = undefined;
294 var unmasked = true;
295 } catch (e) {}
296
297 var result = nativeObjectToString.call(value);
298 if (unmasked) {
299 if (isOwn) {
300 value[symToStringTag$1] = tag;
301 } else {
302 delete value[symToStringTag$1];
303 }
304 }
305 return result;
306}
307
308/** Used for built-in method references. */
309var objectProto$1 = Object.prototype;
310
311/**
312 * Used to resolve the
313 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
314 * of values.
315 */
316var nativeObjectToString$1 = objectProto$1.toString;
317
318/**
319 * Converts `value` to a string using `Object.prototype.toString`.
320 *
321 * @private
322 * @param {*} value The value to convert.
323 * @returns {string} Returns the converted string.
324 */
325function objectToString(value) {
326 return nativeObjectToString$1.call(value);
327}
328
329/** `Object#toString` result references. */
330var nullTag = '[object Null]';
331var undefinedTag = '[object Undefined]';
332
333/** Built-in value references. */
334var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
335
336/**
337 * The base implementation of `getTag` without fallbacks for buggy environments.
338 *
339 * @private
340 * @param {*} value The value to query.
341 * @returns {string} Returns the `toStringTag`.
342 */
343function baseGetTag(value) {
344 if (value == null) {
345 return value === undefined ? undefinedTag : nullTag;
346 }
347 return (symToStringTag && symToStringTag in Object(value))
348 ? getRawTag(value)
349 : objectToString(value);
350}
351
352/** `Object#toString` result references. */
353var asyncTag = '[object AsyncFunction]';
354var funcTag = '[object Function]';
355var genTag = '[object GeneratorFunction]';
356var proxyTag = '[object Proxy]';
357
358/**
359 * Checks if `value` is classified as a `Function` object.
360 *
361 * @static
362 * @memberOf _
363 * @since 0.1.0
364 * @category Lang
365 * @param {*} value The value to check.
366 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
367 * @example
368 *
369 * _.isFunction(_);
370 * // => true
371 *
372 * _.isFunction(/abc/);
373 * // => false
374 */
375function isFunction(value) {
376 if (!isObject(value)) {
377 return false;
378 }
379 // The use of `Object#toString` avoids issues with the `typeof` operator
380 // in Safari 9 which returns 'object' for typed arrays and other constructors.
381 var tag = baseGetTag(value);
382 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
383}
384
385/** Used as references for various `Number` constants. */
386var MAX_SAFE_INTEGER = 9007199254740991;
387
388/**
389 * Checks if `value` is a valid array-like length.
390 *
391 * **Note:** This method is loosely based on
392 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
393 *
394 * @static
395 * @memberOf _
396 * @since 4.0.0
397 * @category Lang
398 * @param {*} value The value to check.
399 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
400 * @example
401 *
402 * _.isLength(3);
403 * // => true
404 *
405 * _.isLength(Number.MIN_VALUE);
406 * // => false
407 *
408 * _.isLength(Infinity);
409 * // => false
410 *
411 * _.isLength('3');
412 * // => false
413 */
414function isLength(value) {
415 return typeof value == 'number' &&
416 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
417}
418
419/**
420 * Checks if `value` is array-like. A value is considered array-like if it's
421 * not a function and has a `value.length` that's an integer greater than or
422 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
423 *
424 * @static
425 * @memberOf _
426 * @since 4.0.0
427 * @category Lang
428 * @param {*} value The value to check.
429 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
430 * @example
431 *
432 * _.isArrayLike([1, 2, 3]);
433 * // => true
434 *
435 * _.isArrayLike(document.body.children);
436 * // => true
437 *
438 * _.isArrayLike('abc');
439 * // => true
440 *
441 * _.isArrayLike(_.noop);
442 * // => false
443 */
444function isArrayLike(value) {
445 return value != null && isLength(value.length) && !isFunction(value);
446}
447
448// A temporary value used to identify if the loop should be broken.
449// See #1064, #1293
450var breakLoop = {};
451
452/**
453 * This method returns `undefined`.
454 *
455 * @static
456 * @memberOf _
457 * @since 2.3.0
458 * @category Util
459 * @example
460 *
461 * _.times(2, _.noop);
462 * // => [undefined, undefined]
463 */
464function noop() {
465 // No operation performed.
466}
467
468function once(fn) {
469 return function () {
470 if (fn === null) return;
471 var callFn = fn;
472 fn = null;
473 callFn.apply(this, arguments);
474 };
475}
476
477var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator;
478
479var getIterator = function (coll) {
480 return iteratorSymbol && coll[iteratorSymbol] && coll[iteratorSymbol]();
481};
482
483/**
484 * The base implementation of `_.times` without support for iteratee shorthands
485 * or max array length checks.
486 *
487 * @private
488 * @param {number} n The number of times to invoke `iteratee`.
489 * @param {Function} iteratee The function invoked per iteration.
490 * @returns {Array} Returns the array of results.
491 */
492function baseTimes(n, iteratee) {
493 var index = -1,
494 result = Array(n);
495
496 while (++index < n) {
497 result[index] = iteratee(index);
498 }
499 return result;
500}
501
502/**
503 * Checks if `value` is object-like. A value is object-like if it's not `null`
504 * and has a `typeof` result of "object".
505 *
506 * @static
507 * @memberOf _
508 * @since 4.0.0
509 * @category Lang
510 * @param {*} value The value to check.
511 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
512 * @example
513 *
514 * _.isObjectLike({});
515 * // => true
516 *
517 * _.isObjectLike([1, 2, 3]);
518 * // => true
519 *
520 * _.isObjectLike(_.noop);
521 * // => false
522 *
523 * _.isObjectLike(null);
524 * // => false
525 */
526function isObjectLike(value) {
527 return value != null && typeof value == 'object';
528}
529
530/** `Object#toString` result references. */
531var argsTag = '[object Arguments]';
532
533/**
534 * The base implementation of `_.isArguments`.
535 *
536 * @private
537 * @param {*} value The value to check.
538 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
539 */
540function baseIsArguments(value) {
541 return isObjectLike(value) && baseGetTag(value) == argsTag;
542}
543
544/** Used for built-in method references. */
545var objectProto$3 = Object.prototype;
546
547/** Used to check objects for own properties. */
548var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
549
550/** Built-in value references. */
551var propertyIsEnumerable = objectProto$3.propertyIsEnumerable;
552
553/**
554 * Checks if `value` is likely an `arguments` object.
555 *
556 * @static
557 * @memberOf _
558 * @since 0.1.0
559 * @category Lang
560 * @param {*} value The value to check.
561 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
562 * else `false`.
563 * @example
564 *
565 * _.isArguments(function() { return arguments; }());
566 * // => true
567 *
568 * _.isArguments([1, 2, 3]);
569 * // => false
570 */
571var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
572 return isObjectLike(value) && hasOwnProperty$2.call(value, 'callee') &&
573 !propertyIsEnumerable.call(value, 'callee');
574};
575
576/**
577 * Checks if `value` is classified as an `Array` object.
578 *
579 * @static
580 * @memberOf _
581 * @since 0.1.0
582 * @category Lang
583 * @param {*} value The value to check.
584 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
585 * @example
586 *
587 * _.isArray([1, 2, 3]);
588 * // => true
589 *
590 * _.isArray(document.body.children);
591 * // => false
592 *
593 * _.isArray('abc');
594 * // => false
595 *
596 * _.isArray(_.noop);
597 * // => false
598 */
599var isArray = Array.isArray;
600
601/**
602 * This method returns `false`.
603 *
604 * @static
605 * @memberOf _
606 * @since 4.13.0
607 * @category Util
608 * @returns {boolean} Returns `false`.
609 * @example
610 *
611 * _.times(2, _.stubFalse);
612 * // => [false, false]
613 */
614function stubFalse() {
615 return false;
616}
617
618/** Detect free variable `exports`. */
619var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
620
621/** Detect free variable `module`. */
622var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
623
624/** Detect the popular CommonJS extension `module.exports`. */
625var moduleExports = freeModule && freeModule.exports === freeExports;
626
627/** Built-in value references. */
628var Buffer = moduleExports ? root.Buffer : undefined;
629
630/* Built-in method references for those with the same name as other `lodash` methods. */
631var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
632
633/**
634 * Checks if `value` is a buffer.
635 *
636 * @static
637 * @memberOf _
638 * @since 4.3.0
639 * @category Lang
640 * @param {*} value The value to check.
641 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
642 * @example
643 *
644 * _.isBuffer(new Buffer(2));
645 * // => true
646 *
647 * _.isBuffer(new Uint8Array(2));
648 * // => false
649 */
650var isBuffer = nativeIsBuffer || stubFalse;
651
652/** Used as references for various `Number` constants. */
653var MAX_SAFE_INTEGER$1 = 9007199254740991;
654
655/** Used to detect unsigned integer values. */
656var reIsUint = /^(?:0|[1-9]\d*)$/;
657
658/**
659 * Checks if `value` is a valid array-like index.
660 *
661 * @private
662 * @param {*} value The value to check.
663 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
664 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
665 */
666function isIndex(value, length) {
667 var type = typeof value;
668 length = length == null ? MAX_SAFE_INTEGER$1 : length;
669
670 return !!length &&
671 (type == 'number' ||
672 (type != 'symbol' && reIsUint.test(value))) &&
673 (value > -1 && value % 1 == 0 && value < length);
674}
675
676/** `Object#toString` result references. */
677var argsTag$1 = '[object Arguments]';
678var arrayTag = '[object Array]';
679var boolTag = '[object Boolean]';
680var dateTag = '[object Date]';
681var errorTag = '[object Error]';
682var funcTag$1 = '[object Function]';
683var mapTag = '[object Map]';
684var numberTag = '[object Number]';
685var objectTag = '[object Object]';
686var regexpTag = '[object RegExp]';
687var setTag = '[object Set]';
688var stringTag = '[object String]';
689var weakMapTag = '[object WeakMap]';
690
691var arrayBufferTag = '[object ArrayBuffer]';
692var dataViewTag = '[object DataView]';
693var float32Tag = '[object Float32Array]';
694var float64Tag = '[object Float64Array]';
695var int8Tag = '[object Int8Array]';
696var int16Tag = '[object Int16Array]';
697var int32Tag = '[object Int32Array]';
698var uint8Tag = '[object Uint8Array]';
699var uint8ClampedTag = '[object Uint8ClampedArray]';
700var uint16Tag = '[object Uint16Array]';
701var uint32Tag = '[object Uint32Array]';
702
703/** Used to identify `toStringTag` values of typed arrays. */
704var typedArrayTags = {};
705typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
706typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
707typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
708typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
709typedArrayTags[uint32Tag] = true;
710typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
711typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
712typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
713typedArrayTags[errorTag] = typedArrayTags[funcTag$1] =
714typedArrayTags[mapTag] = typedArrayTags[numberTag] =
715typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
716typedArrayTags[setTag] = typedArrayTags[stringTag] =
717typedArrayTags[weakMapTag] = false;
718
719/**
720 * The base implementation of `_.isTypedArray` without Node.js optimizations.
721 *
722 * @private
723 * @param {*} value The value to check.
724 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
725 */
726function baseIsTypedArray(value) {
727 return isObjectLike(value) &&
728 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
729}
730
731/**
732 * The base implementation of `_.unary` without support for storing metadata.
733 *
734 * @private
735 * @param {Function} func The function to cap arguments for.
736 * @returns {Function} Returns the new capped function.
737 */
738function baseUnary(func) {
739 return function(value) {
740 return func(value);
741 };
742}
743
744/** Detect free variable `exports`. */
745var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
746
747/** Detect free variable `module`. */
748var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
749
750/** Detect the popular CommonJS extension `module.exports`. */
751var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
752
753/** Detect free variable `process` from Node.js. */
754var freeProcess = moduleExports$1 && freeGlobal.process;
755
756/** Used to access faster Node.js helpers. */
757var nodeUtil = (function() {
758 try {
759 // Use `util.types` for Node.js 10+.
760 var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types;
761
762 if (types) {
763 return types;
764 }
765
766 // Legacy `process.binding('util')` for Node.js < 10.
767 return freeProcess && freeProcess.binding && freeProcess.binding('util');
768 } catch (e) {}
769}());
770
771/* Node.js helper references. */
772var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
773
774/**
775 * Checks if `value` is classified as a typed array.
776 *
777 * @static
778 * @memberOf _
779 * @since 3.0.0
780 * @category Lang
781 * @param {*} value The value to check.
782 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
783 * @example
784 *
785 * _.isTypedArray(new Uint8Array);
786 * // => true
787 *
788 * _.isTypedArray([]);
789 * // => false
790 */
791var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
792
793/** Used for built-in method references. */
794var objectProto$2 = Object.prototype;
795
796/** Used to check objects for own properties. */
797var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
798
799/**
800 * Creates an array of the enumerable property names of the array-like `value`.
801 *
802 * @private
803 * @param {*} value The value to query.
804 * @param {boolean} inherited Specify returning inherited property names.
805 * @returns {Array} Returns the array of property names.
806 */
807function arrayLikeKeys(value, inherited) {
808 var isArr = isArray(value),
809 isArg = !isArr && isArguments(value),
810 isBuff = !isArr && !isArg && isBuffer(value),
811 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
812 skipIndexes = isArr || isArg || isBuff || isType,
813 result = skipIndexes ? baseTimes(value.length, String) : [],
814 length = result.length;
815
816 for (var key in value) {
817 if ((inherited || hasOwnProperty$1.call(value, key)) &&
818 !(skipIndexes && (
819 // Safari 9 has enumerable `arguments.length` in strict mode.
820 key == 'length' ||
821 // Node.js 0.10 has enumerable non-index properties on buffers.
822 (isBuff && (key == 'offset' || key == 'parent')) ||
823 // PhantomJS 2 has enumerable non-index properties on typed arrays.
824 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
825 // Skip index properties.
826 isIndex(key, length)
827 ))) {
828 result.push(key);
829 }
830 }
831 return result;
832}
833
834/** Used for built-in method references. */
835var objectProto$5 = Object.prototype;
836
837/**
838 * Checks if `value` is likely a prototype object.
839 *
840 * @private
841 * @param {*} value The value to check.
842 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
843 */
844function isPrototype(value) {
845 var Ctor = value && value.constructor,
846 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5;
847
848 return value === proto;
849}
850
851/**
852 * Creates a unary function that invokes `func` with its argument transformed.
853 *
854 * @private
855 * @param {Function} func The function to wrap.
856 * @param {Function} transform The argument transform.
857 * @returns {Function} Returns the new function.
858 */
859function overArg(func, transform) {
860 return function(arg) {
861 return func(transform(arg));
862 };
863}
864
865/* Built-in method references for those with the same name as other `lodash` methods. */
866var nativeKeys = overArg(Object.keys, Object);
867
868/** Used for built-in method references. */
869var objectProto$4 = Object.prototype;
870
871/** Used to check objects for own properties. */
872var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
873
874/**
875 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
876 *
877 * @private
878 * @param {Object} object The object to query.
879 * @returns {Array} Returns the array of property names.
880 */
881function baseKeys(object) {
882 if (!isPrototype(object)) {
883 return nativeKeys(object);
884 }
885 var result = [];
886 for (var key in Object(object)) {
887 if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
888 result.push(key);
889 }
890 }
891 return result;
892}
893
894/**
895 * Creates an array of the own enumerable property names of `object`.
896 *
897 * **Note:** Non-object values are coerced to objects. See the
898 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
899 * for more details.
900 *
901 * @static
902 * @since 0.1.0
903 * @memberOf _
904 * @category Object
905 * @param {Object} object The object to query.
906 * @returns {Array} Returns the array of property names.
907 * @example
908 *
909 * function Foo() {
910 * this.a = 1;
911 * this.b = 2;
912 * }
913 *
914 * Foo.prototype.c = 3;
915 *
916 * _.keys(new Foo);
917 * // => ['a', 'b'] (iteration order is not guaranteed)
918 *
919 * _.keys('hi');
920 * // => ['0', '1']
921 */
922function keys(object) {
923 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
924}
925
926function createArrayIterator(coll) {
927 var i = -1;
928 var len = coll.length;
929 return function next() {
930 return ++i < len ? {value: coll[i], key: i} : null;
931 }
932}
933
934function createES2015Iterator(iterator) {
935 var i = -1;
936 return function next() {
937 var item = iterator.next();
938 if (item.done)
939 return null;
940 i++;
941 return {value: item.value, key: i};
942 }
943}
944
945function createObjectIterator(obj) {
946 var okeys = keys(obj);
947 var i = -1;
948 var len = okeys.length;
949 return function next() {
950 var key = okeys[++i];
951 return i < len ? {value: obj[key], key: key} : null;
952 };
953}
954
955function iterator(coll) {
956 if (isArrayLike(coll)) {
957 return createArrayIterator(coll);
958 }
959
960 var iterator = getIterator(coll);
961 return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
962}
963
964function onlyOnce(fn) {
965 return function() {
966 if (fn === null) throw new Error("Callback was already called.");
967 var callFn = fn;
968 fn = null;
969 callFn.apply(this, arguments);
970 };
971}
972
973function _eachOfLimit(limit) {
974 return function (obj, iteratee, callback) {
975 callback = once(callback || noop);
976 if (limit <= 0 || !obj) {
977 return callback(null);
978 }
979 var nextElem = iterator(obj);
980 var done = false;
981 var running = 0;
982 var looping = false;
983
984 function iterateeCallback(err, value) {
985 running -= 1;
986 if (err) {
987 done = true;
988 callback(err);
989 }
990 else if (value === breakLoop || (done && running <= 0)) {
991 done = true;
992 return callback(null);
993 }
994 else if (!looping) {
995 replenish();
996 }
997 }
998
999 function replenish () {
1000 looping = true;
1001 while (running < limit && !done) {
1002 var elem = nextElem();
1003 if (elem === null) {
1004 done = true;
1005 if (running <= 0) {
1006 callback(null);
1007 }
1008 return;
1009 }
1010 running += 1;
1011 iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
1012 }
1013 looping = false;
1014 }
1015
1016 replenish();
1017 };
1018}
1019
1020/**
1021 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
1022 * time.
1023 *
1024 * @name eachOfLimit
1025 * @static
1026 * @memberOf module:Collections
1027 * @method
1028 * @see [async.eachOf]{@link module:Collections.eachOf}
1029 * @alias forEachOfLimit
1030 * @category Collection
1031 * @param {Array|Iterable|Object} coll - A collection to iterate over.
1032 * @param {number} limit - The maximum number of async operations at a time.
1033 * @param {AsyncFunction} iteratee - An async function to apply to each
1034 * item in `coll`. The `key` is the item's key, or index in the case of an
1035 * array.
1036 * Invoked with (item, key, callback).
1037 * @param {Function} [callback] - A callback which is called when all
1038 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
1039 */
1040function eachOfLimit(coll, limit, iteratee, callback) {
1041 _eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
1042}
1043
1044function doLimit(fn, limit) {
1045 return function (iterable, iteratee, callback) {
1046 return fn(iterable, limit, iteratee, callback);
1047 };
1048}
1049
1050// eachOf implementation optimized for array-likes
1051function eachOfArrayLike(coll, iteratee, callback) {
1052 callback = once(callback || noop);
1053 var index = 0,
1054 completed = 0,
1055 length = coll.length;
1056 if (length === 0) {
1057 callback(null);
1058 }
1059
1060 function iteratorCallback(err, value) {
1061 if (err) {
1062 callback(err);
1063 } else if ((++completed === length) || value === breakLoop) {
1064 callback(null);
1065 }
1066 }
1067
1068 for (; index < length; index++) {
1069 iteratee(coll[index], index, onlyOnce(iteratorCallback));
1070 }
1071}
1072
1073// a generic version of eachOf which can handle array, object, and iterator cases.
1074var eachOfGeneric = doLimit(eachOfLimit, Infinity);
1075
1076/**
1077 * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
1078 * to the iteratee.
1079 *
1080 * @name eachOf
1081 * @static
1082 * @memberOf module:Collections
1083 * @method
1084 * @alias forEachOf
1085 * @category Collection
1086 * @see [async.each]{@link module:Collections.each}
1087 * @param {Array|Iterable|Object} coll - A collection to iterate over.
1088 * @param {AsyncFunction} iteratee - A function to apply to each
1089 * item in `coll`.
1090 * The `key` is the item's key, or index in the case of an array.
1091 * Invoked with (item, key, callback).
1092 * @param {Function} [callback] - A callback which is called when all
1093 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
1094 * @example
1095 *
1096 * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
1097 * var configs = {};
1098 *
1099 * async.forEachOf(obj, function (value, key, callback) {
1100 * fs.readFile(__dirname + value, "utf8", function (err, data) {
1101 * if (err) return callback(err);
1102 * try {
1103 * configs[key] = JSON.parse(data);
1104 * } catch (e) {
1105 * return callback(e);
1106 * }
1107 * callback();
1108 * });
1109 * }, function (err) {
1110 * if (err) console.error(err.message);
1111 * // configs is now a map of JSON data
1112 * doSomethingWith(configs);
1113 * });
1114 */
1115var eachOf = function(coll, iteratee, callback) {
1116 var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
1117 eachOfImplementation(coll, wrapAsync(iteratee), callback);
1118};
1119
1120function doParallel(fn) {
1121 return function (obj, iteratee, callback) {
1122 return fn(eachOf, obj, wrapAsync(iteratee), callback);
1123 };
1124}
1125
1126function _asyncMap(eachfn, arr, iteratee, callback) {
1127 callback = callback || noop;
1128 arr = arr || [];
1129 var results = [];
1130 var counter = 0;
1131 var _iteratee = wrapAsync(iteratee);
1132
1133 eachfn(arr, function (value, _, callback) {
1134 var index = counter++;
1135 _iteratee(value, function (err, v) {
1136 results[index] = v;
1137 callback(err);
1138 });
1139 }, function (err) {
1140 callback(err, results);
1141 });
1142}
1143
1144/**
1145 * Produces a new collection of values by mapping each value in `coll` through
1146 * the `iteratee` function. The `iteratee` is called with an item from `coll`
1147 * and a callback for when it has finished processing. Each of these callback
1148 * takes 2 arguments: an `error`, and the transformed item from `coll`. If
1149 * `iteratee` passes an error to its callback, the main `callback` (for the
1150 * `map` function) is immediately called with the error.
1151 *
1152 * Note, that since this function applies the `iteratee` to each item in
1153 * parallel, there is no guarantee that the `iteratee` functions will complete
1154 * in order. However, the results array will be in the same order as the
1155 * original `coll`.
1156 *
1157 * If `map` is passed an Object, the results will be an Array. The results
1158 * will roughly be in the order of the original Objects' keys (but this can
1159 * vary across JavaScript engines).
1160 *
1161 * @name map
1162 * @static
1163 * @memberOf module:Collections
1164 * @method
1165 * @category Collection
1166 * @param {Array|Iterable|Object} coll - A collection to iterate over.
1167 * @param {AsyncFunction} iteratee - An async function to apply to each item in
1168 * `coll`.
1169 * The iteratee should complete with the transformed item.
1170 * Invoked with (item, callback).
1171 * @param {Function} [callback] - A callback which is called when all `iteratee`
1172 * functions have finished, or an error occurs. Results is an Array of the
1173 * transformed items from the `coll`. Invoked with (err, results).
1174 * @example
1175 *
1176 * async.map(['file1','file2','file3'], fs.stat, function(err, results) {
1177 * // results is now an array of stats for each file
1178 * });
1179 */
1180var map = doParallel(_asyncMap);
1181
1182/**
1183 * Applies the provided arguments to each function in the array, calling
1184 * `callback` after all functions have completed. If you only provide the first
1185 * argument, `fns`, then it will return a function which lets you pass in the
1186 * arguments as if it were a single function call. If more arguments are
1187 * provided, `callback` is required while `args` is still optional.
1188 *
1189 * @name applyEach
1190 * @static
1191 * @memberOf module:ControlFlow
1192 * @method
1193 * @category Control Flow
1194 * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s
1195 * to all call with the same arguments
1196 * @param {...*} [args] - any number of separate arguments to pass to the
1197 * function.
1198 * @param {Function} [callback] - the final argument should be the callback,
1199 * called when all functions have completed processing.
1200 * @returns {Function} - If only the first argument, `fns`, is provided, it will
1201 * return a function which lets you pass in the arguments as if it were a single
1202 * function call. The signature is `(..args, callback)`. If invoked with any
1203 * arguments, `callback` is required.
1204 * @example
1205 *
1206 * async.applyEach([enableSearch, updateSchema], 'bucket', callback);
1207 *
1208 * // partial application example:
1209 * async.each(
1210 * buckets,
1211 * async.applyEach([enableSearch, updateSchema]),
1212 * callback
1213 * );
1214 */
1215var applyEach = applyEach$1(map);
1216
1217function doParallelLimit(fn) {
1218 return function (obj, limit, iteratee, callback) {
1219 return fn(_eachOfLimit(limit), obj, wrapAsync(iteratee), callback);
1220 };
1221}
1222
1223/**
1224 * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
1225 *
1226 * @name mapLimit
1227 * @static
1228 * @memberOf module:Collections
1229 * @method
1230 * @see [async.map]{@link module:Collections.map}
1231 * @category Collection
1232 * @param {Array|Iterable|Object} coll - A collection to iterate over.
1233 * @param {number} limit - The maximum number of async operations at a time.
1234 * @param {AsyncFunction} iteratee - An async function to apply to each item in
1235 * `coll`.
1236 * The iteratee should complete with the transformed item.
1237 * Invoked with (item, callback).
1238 * @param {Function} [callback] - A callback which is called when all `iteratee`
1239 * functions have finished, or an error occurs. Results is an array of the
1240 * transformed items from the `coll`. Invoked with (err, results).
1241 */
1242var mapLimit = doParallelLimit(_asyncMap);
1243
1244/**
1245 * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
1246 *
1247 * @name mapSeries
1248 * @static
1249 * @memberOf module:Collections
1250 * @method
1251 * @see [async.map]{@link module:Collections.map}
1252 * @category Collection
1253 * @param {Array|Iterable|Object} coll - A collection to iterate over.
1254 * @param {AsyncFunction} iteratee - An async function to apply to each item in
1255 * `coll`.
1256 * The iteratee should complete with the transformed item.
1257 * Invoked with (item, callback).
1258 * @param {Function} [callback] - A callback which is called when all `iteratee`
1259 * functions have finished, or an error occurs. Results is an array of the
1260 * transformed items from the `coll`. Invoked with (err, results).
1261 */
1262var mapSeries = doLimit(mapLimit, 1);
1263
1264/**
1265 * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
1266 *
1267 * @name applyEachSeries
1268 * @static
1269 * @memberOf module:ControlFlow
1270 * @method
1271 * @see [async.applyEach]{@link module:ControlFlow.applyEach}
1272 * @category Control Flow
1273 * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s to all
1274 * call with the same arguments
1275 * @param {...*} [args] - any number of separate arguments to pass to the
1276 * function.
1277 * @param {Function} [callback] - the final argument should be the callback,
1278 * called when all functions have completed processing.
1279 * @returns {Function} - If only the first argument is provided, it will return
1280 * a function which lets you pass in the arguments as if it were a single
1281 * function call.
1282 */
1283var applyEachSeries = applyEach$1(mapSeries);
1284
1285/**
1286 * A specialized version of `_.forEach` for arrays without support for
1287 * iteratee shorthands.
1288 *
1289 * @private
1290 * @param {Array} [array] The array to iterate over.
1291 * @param {Function} iteratee The function invoked per iteration.
1292 * @returns {Array} Returns `array`.
1293 */
1294function arrayEach(array, iteratee) {
1295 var index = -1,
1296 length = array == null ? 0 : array.length;
1297
1298 while (++index < length) {
1299 if (iteratee(array[index], index, array) === false) {
1300 break;
1301 }
1302 }
1303 return array;
1304}
1305
1306/**
1307 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
1308 *
1309 * @private
1310 * @param {boolean} [fromRight] Specify iterating from right to left.
1311 * @returns {Function} Returns the new base function.
1312 */
1313function createBaseFor(fromRight) {
1314 return function(object, iteratee, keysFunc) {
1315 var index = -1,
1316 iterable = Object(object),
1317 props = keysFunc(object),
1318 length = props.length;
1319
1320 while (length--) {
1321 var key = props[fromRight ? length : ++index];
1322 if (iteratee(iterable[key], key, iterable) === false) {
1323 break;
1324 }
1325 }
1326 return object;
1327 };
1328}
1329
1330/**
1331 * The base implementation of `baseForOwn` which iterates over `object`
1332 * properties returned by `keysFunc` and invokes `iteratee` for each property.
1333 * Iteratee functions may exit iteration early by explicitly returning `false`.
1334 *
1335 * @private
1336 * @param {Object} object The object to iterate over.
1337 * @param {Function} iteratee The function invoked per iteration.
1338 * @param {Function} keysFunc The function to get the keys of `object`.
1339 * @returns {Object} Returns `object`.
1340 */
1341var baseFor = createBaseFor();
1342
1343/**
1344 * The base implementation of `_.forOwn` without support for iteratee shorthands.
1345 *
1346 * @private
1347 * @param {Object} object The object to iterate over.
1348 * @param {Function} iteratee The function invoked per iteration.
1349 * @returns {Object} Returns `object`.
1350 */
1351function baseForOwn(object, iteratee) {
1352 return object && baseFor(object, iteratee, keys);
1353}
1354
1355/**
1356 * The base implementation of `_.findIndex` and `_.findLastIndex` without
1357 * support for iteratee shorthands.
1358 *
1359 * @private
1360 * @param {Array} array The array to inspect.
1361 * @param {Function} predicate The function invoked per iteration.
1362 * @param {number} fromIndex The index to search from.
1363 * @param {boolean} [fromRight] Specify iterating from right to left.
1364 * @returns {number} Returns the index of the matched value, else `-1`.
1365 */
1366function baseFindIndex(array, predicate, fromIndex, fromRight) {
1367 var length = array.length,
1368 index = fromIndex + (fromRight ? 1 : -1);
1369
1370 while ((fromRight ? index-- : ++index < length)) {
1371 if (predicate(array[index], index, array)) {
1372 return index;
1373 }
1374 }
1375 return -1;
1376}
1377
1378/**
1379 * The base implementation of `_.isNaN` without support for number objects.
1380 *
1381 * @private
1382 * @param {*} value The value to check.
1383 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
1384 */
1385function baseIsNaN(value) {
1386 return value !== value;
1387}
1388
1389/**
1390 * A specialized version of `_.indexOf` which performs strict equality
1391 * comparisons of values, i.e. `===`.
1392 *
1393 * @private
1394 * @param {Array} array The array to inspect.
1395 * @param {*} value The value to search for.
1396 * @param {number} fromIndex The index to search from.
1397 * @returns {number} Returns the index of the matched value, else `-1`.
1398 */
1399function strictIndexOf(array, value, fromIndex) {
1400 var index = fromIndex - 1,
1401 length = array.length;
1402
1403 while (++index < length) {
1404 if (array[index] === value) {
1405 return index;
1406 }
1407 }
1408 return -1;
1409}
1410
1411/**
1412 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
1413 *
1414 * @private
1415 * @param {Array} array The array to inspect.
1416 * @param {*} value The value to search for.
1417 * @param {number} fromIndex The index to search from.
1418 * @returns {number} Returns the index of the matched value, else `-1`.
1419 */
1420function baseIndexOf(array, value, fromIndex) {
1421 return value === value
1422 ? strictIndexOf(array, value, fromIndex)
1423 : baseFindIndex(array, baseIsNaN, fromIndex);
1424}
1425
1426/**
1427 * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
1428 * their requirements. Each function can optionally depend on other functions
1429 * being completed first, and each function is run as soon as its requirements
1430 * are satisfied.
1431 *
1432 * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
1433 * will stop. Further tasks will not execute (so any other functions depending
1434 * on it will not run), and the main `callback` is immediately called with the
1435 * error.
1436 *
1437 * {@link AsyncFunction}s also receive an object containing the results of functions which
1438 * have completed so far as the first argument, if they have dependencies. If a
1439 * task function has no dependencies, it will only be passed a callback.
1440 *
1441 * @name auto
1442 * @static
1443 * @memberOf module:ControlFlow
1444 * @method
1445 * @category Control Flow
1446 * @param {Object} tasks - An object. Each of its properties is either a
1447 * function or an array of requirements, with the {@link AsyncFunction} itself the last item
1448 * in the array. The object's key of a property serves as the name of the task
1449 * defined by that property, i.e. can be used when specifying requirements for
1450 * other tasks. The function receives one or two arguments:
1451 * * a `results` object, containing the results of the previously executed
1452 * functions, only passed if the task has any dependencies,
1453 * * a `callback(err, result)` function, which must be called when finished,
1454 * passing an `error` (which can be `null`) and the result of the function's
1455 * execution.
1456 * @param {number} [concurrency=Infinity] - An optional `integer` for
1457 * determining the maximum number of tasks that can be run in parallel. By
1458 * default, as many as possible.
1459 * @param {Function} [callback] - An optional callback which is called when all
1460 * the tasks have been completed. It receives the `err` argument if any `tasks`
1461 * pass an error to their callback. Results are always returned; however, if an
1462 * error occurs, no further `tasks` will be performed, and the results object
1463 * will only contain partial results. Invoked with (err, results).
1464 * @returns undefined
1465 * @example
1466 *
1467 * async.auto({
1468 * // this function will just be passed a callback
1469 * readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
1470 * showData: ['readData', function(results, cb) {
1471 * // results.readData is the file's contents
1472 * // ...
1473 * }]
1474 * }, callback);
1475 *
1476 * async.auto({
1477 * get_data: function(callback) {
1478 * console.log('in get_data');
1479 * // async code to get some data
1480 * callback(null, 'data', 'converted to array');
1481 * },
1482 * make_folder: function(callback) {
1483 * console.log('in make_folder');
1484 * // async code to create a directory to store a file in
1485 * // this is run at the same time as getting the data
1486 * callback(null, 'folder');
1487 * },
1488 * write_file: ['get_data', 'make_folder', function(results, callback) {
1489 * console.log('in write_file', JSON.stringify(results));
1490 * // once there is some data and the directory exists,
1491 * // write the data to a file in the directory
1492 * callback(null, 'filename');
1493 * }],
1494 * email_link: ['write_file', function(results, callback) {
1495 * console.log('in email_link', JSON.stringify(results));
1496 * // once the file is written let's email a link to it...
1497 * // results.write_file contains the filename returned by write_file.
1498 * callback(null, {'file':results.write_file, 'email':'user@example.com'});
1499 * }]
1500 * }, function(err, results) {
1501 * console.log('err = ', err);
1502 * console.log('results = ', results);
1503 * });
1504 */
1505var auto = function (tasks, concurrency, callback) {
1506 if (typeof concurrency === 'function') {
1507 // concurrency is optional, shift the args.
1508 callback = concurrency;
1509 concurrency = null;
1510 }
1511 callback = once(callback || noop);
1512 var keys$$1 = keys(tasks);
1513 var numTasks = keys$$1.length;
1514 if (!numTasks) {
1515 return callback(null);
1516 }
1517 if (!concurrency) {
1518 concurrency = numTasks;
1519 }
1520
1521 var results = {};
1522 var runningTasks = 0;
1523 var hasError = false;
1524
1525 var listeners = Object.create(null);
1526
1527 var readyTasks = [];
1528
1529 // for cycle detection:
1530 var readyToCheck = []; // tasks that have been identified as reachable
1531 // without the possibility of returning to an ancestor task
1532 var uncheckedDependencies = {};
1533
1534 baseForOwn(tasks, function (task, key) {
1535 if (!isArray(task)) {
1536 // no dependencies
1537 enqueueTask(key, [task]);
1538 readyToCheck.push(key);
1539 return;
1540 }
1541
1542 var dependencies = task.slice(0, task.length - 1);
1543 var remainingDependencies = dependencies.length;
1544 if (remainingDependencies === 0) {
1545 enqueueTask(key, task);
1546 readyToCheck.push(key);
1547 return;
1548 }
1549 uncheckedDependencies[key] = remainingDependencies;
1550
1551 arrayEach(dependencies, function (dependencyName) {
1552 if (!tasks[dependencyName]) {
1553 throw new Error('async.auto task `' + key +
1554 '` has a non-existent dependency `' +
1555 dependencyName + '` in ' +
1556 dependencies.join(', '));
1557 }
1558 addListener(dependencyName, function () {
1559 remainingDependencies--;
1560 if (remainingDependencies === 0) {
1561 enqueueTask(key, task);
1562 }
1563 });
1564 });
1565 });
1566
1567 checkForDeadlocks();
1568 processQueue();
1569
1570 function enqueueTask(key, task) {
1571 readyTasks.push(function () {
1572 runTask(key, task);
1573 });
1574 }
1575
1576 function processQueue() {
1577 if (readyTasks.length === 0 && runningTasks === 0) {
1578 return callback(null, results);
1579 }
1580 while(readyTasks.length && runningTasks < concurrency) {
1581 var run = readyTasks.shift();
1582 run();
1583 }
1584
1585 }
1586
1587 function addListener(taskName, fn) {
1588 var taskListeners = listeners[taskName];
1589 if (!taskListeners) {
1590 taskListeners = listeners[taskName] = [];
1591 }
1592
1593 taskListeners.push(fn);
1594 }
1595
1596 function taskComplete(taskName) {
1597 var taskListeners = listeners[taskName] || [];
1598 arrayEach(taskListeners, function (fn) {
1599 fn();
1600 });
1601 processQueue();
1602 }
1603
1604
1605 function runTask(key, task) {
1606 if (hasError) return;
1607
1608 var taskCallback = onlyOnce(function(err, result) {
1609 runningTasks--;
1610 if (arguments.length > 2) {
1611 result = slice(arguments, 1);
1612 }
1613 if (err) {
1614 var safeResults = {};
1615 baseForOwn(results, function(val, rkey) {
1616 safeResults[rkey] = val;
1617 });
1618 safeResults[key] = result;
1619 hasError = true;
1620 listeners = Object.create(null);
1621
1622 callback(err, safeResults);
1623 } else {
1624 results[key] = result;
1625 taskComplete(key);
1626 }
1627 });
1628
1629 runningTasks++;
1630 var taskFn = wrapAsync(task[task.length - 1]);
1631 if (task.length > 1) {
1632 taskFn(results, taskCallback);
1633 } else {
1634 taskFn(taskCallback);
1635 }
1636 }
1637
1638 function checkForDeadlocks() {
1639 // Kahn's algorithm
1640 // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
1641 // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
1642 var currentTask;
1643 var counter = 0;
1644 while (readyToCheck.length) {
1645 currentTask = readyToCheck.pop();
1646 counter++;
1647 arrayEach(getDependents(currentTask), function (dependent) {
1648 if (--uncheckedDependencies[dependent] === 0) {
1649 readyToCheck.push(dependent);
1650 }
1651 });
1652 }
1653
1654 if (counter !== numTasks) {
1655 throw new Error(
1656 'async.auto cannot execute tasks due to a recursive dependency'
1657 );
1658 }
1659 }
1660
1661 function getDependents(taskName) {
1662 var result = [];
1663 baseForOwn(tasks, function (task, key) {
1664 if (isArray(task) && baseIndexOf(task, taskName, 0) >= 0) {
1665 result.push(key);
1666 }
1667 });
1668 return result;
1669 }
1670};
1671
1672/**
1673 * A specialized version of `_.map` for arrays without support for iteratee
1674 * shorthands.
1675 *
1676 * @private
1677 * @param {Array} [array] The array to iterate over.
1678 * @param {Function} iteratee The function invoked per iteration.
1679 * @returns {Array} Returns the new mapped array.
1680 */
1681function arrayMap(array, iteratee) {
1682 var index = -1,
1683 length = array == null ? 0 : array.length,
1684 result = Array(length);
1685
1686 while (++index < length) {
1687 result[index] = iteratee(array[index], index, array);
1688 }
1689 return result;
1690}
1691
1692/** `Object#toString` result references. */
1693var symbolTag = '[object Symbol]';
1694
1695/**
1696 * Checks if `value` is classified as a `Symbol` primitive or object.
1697 *
1698 * @static
1699 * @memberOf _
1700 * @since 4.0.0
1701 * @category Lang
1702 * @param {*} value The value to check.
1703 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
1704 * @example
1705 *
1706 * _.isSymbol(Symbol.iterator);
1707 * // => true
1708 *
1709 * _.isSymbol('abc');
1710 * // => false
1711 */
1712function isSymbol(value) {
1713 return typeof value == 'symbol' ||
1714 (isObjectLike(value) && baseGetTag(value) == symbolTag);
1715}
1716
1717/** Used as references for various `Number` constants. */
1718var INFINITY = 1 / 0;
1719
1720/** Used to convert symbols to primitives and strings. */
1721var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined;
1722var symbolToString = symbolProto ? symbolProto.toString : undefined;
1723
1724/**
1725 * The base implementation of `_.toString` which doesn't convert nullish
1726 * values to empty strings.
1727 *
1728 * @private
1729 * @param {*} value The value to process.
1730 * @returns {string} Returns the string.
1731 */
1732function baseToString(value) {
1733 // Exit early for strings to avoid a performance hit in some environments.
1734 if (typeof value == 'string') {
1735 return value;
1736 }
1737 if (isArray(value)) {
1738 // Recursively convert values (susceptible to call stack limits).
1739 return arrayMap(value, baseToString) + '';
1740 }
1741 if (isSymbol(value)) {
1742 return symbolToString ? symbolToString.call(value) : '';
1743 }
1744 var result = (value + '');
1745 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
1746}
1747
1748/**
1749 * The base implementation of `_.slice` without an iteratee call guard.
1750 *
1751 * @private
1752 * @param {Array} array The array to slice.
1753 * @param {number} [start=0] The start position.
1754 * @param {number} [end=array.length] The end position.
1755 * @returns {Array} Returns the slice of `array`.
1756 */
1757function baseSlice(array, start, end) {
1758 var index = -1,
1759 length = array.length;
1760
1761 if (start < 0) {
1762 start = -start > length ? 0 : (length + start);
1763 }
1764 end = end > length ? length : end;
1765 if (end < 0) {
1766 end += length;
1767 }
1768 length = start > end ? 0 : ((end - start) >>> 0);
1769 start >>>= 0;
1770
1771 var result = Array(length);
1772 while (++index < length) {
1773 result[index] = array[index + start];
1774 }
1775 return result;
1776}
1777
1778/**
1779 * Casts `array` to a slice if it's needed.
1780 *
1781 * @private
1782 * @param {Array} array The array to inspect.
1783 * @param {number} start The start position.
1784 * @param {number} [end=array.length] The end position.
1785 * @returns {Array} Returns the cast slice.
1786 */
1787function castSlice(array, start, end) {
1788 var length = array.length;
1789 end = end === undefined ? length : end;
1790 return (!start && end >= length) ? array : baseSlice(array, start, end);
1791}
1792
1793/**
1794 * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1795 * that is not found in the character symbols.
1796 *
1797 * @private
1798 * @param {Array} strSymbols The string symbols to inspect.
1799 * @param {Array} chrSymbols The character symbols to find.
1800 * @returns {number} Returns the index of the last unmatched string symbol.
1801 */
1802function charsEndIndex(strSymbols, chrSymbols) {
1803 var index = strSymbols.length;
1804
1805 while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1806 return index;
1807}
1808
1809/**
1810 * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1811 * that is not found in the character symbols.
1812 *
1813 * @private
1814 * @param {Array} strSymbols The string symbols to inspect.
1815 * @param {Array} chrSymbols The character symbols to find.
1816 * @returns {number} Returns the index of the first unmatched string symbol.
1817 */
1818function charsStartIndex(strSymbols, chrSymbols) {
1819 var index = -1,
1820 length = strSymbols.length;
1821
1822 while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1823 return index;
1824}
1825
1826/**
1827 * Converts an ASCII `string` to an array.
1828 *
1829 * @private
1830 * @param {string} string The string to convert.
1831 * @returns {Array} Returns the converted array.
1832 */
1833function asciiToArray(string) {
1834 return string.split('');
1835}
1836
1837/** Used to compose unicode character classes. */
1838var rsAstralRange = '\\ud800-\\udfff';
1839var rsComboMarksRange = '\\u0300-\\u036f';
1840var reComboHalfMarksRange = '\\ufe20-\\ufe2f';
1841var rsComboSymbolsRange = '\\u20d0-\\u20ff';
1842var rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange;
1843var rsVarRange = '\\ufe0e\\ufe0f';
1844
1845/** Used to compose unicode capture groups. */
1846var rsZWJ = '\\u200d';
1847
1848/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
1849var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
1850
1851/**
1852 * Checks if `string` contains Unicode symbols.
1853 *
1854 * @private
1855 * @param {string} string The string to inspect.
1856 * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1857 */
1858function hasUnicode(string) {
1859 return reHasUnicode.test(string);
1860}
1861
1862/** Used to compose unicode character classes. */
1863var rsAstralRange$1 = '\\ud800-\\udfff';
1864var rsComboMarksRange$1 = '\\u0300-\\u036f';
1865var reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f';
1866var rsComboSymbolsRange$1 = '\\u20d0-\\u20ff';
1867var rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1;
1868var rsVarRange$1 = '\\ufe0e\\ufe0f';
1869
1870/** Used to compose unicode capture groups. */
1871var rsAstral = '[' + rsAstralRange$1 + ']';
1872var rsCombo = '[' + rsComboRange$1 + ']';
1873var rsFitz = '\\ud83c[\\udffb-\\udfff]';
1874var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')';
1875var rsNonAstral = '[^' + rsAstralRange$1 + ']';
1876var rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}';
1877var rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]';
1878var rsZWJ$1 = '\\u200d';
1879
1880/** Used to compose unicode regexes. */
1881var reOptMod = rsModifier + '?';
1882var rsOptVar = '[' + rsVarRange$1 + ']?';
1883var rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*';
1884var rsSeq = rsOptVar + reOptMod + rsOptJoin;
1885var rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
1886
1887/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
1888var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
1889
1890/**
1891 * Converts a Unicode `string` to an array.
1892 *
1893 * @private
1894 * @param {string} string The string to convert.
1895 * @returns {Array} Returns the converted array.
1896 */
1897function unicodeToArray(string) {
1898 return string.match(reUnicode) || [];
1899}
1900
1901/**
1902 * Converts `string` to an array.
1903 *
1904 * @private
1905 * @param {string} string The string to convert.
1906 * @returns {Array} Returns the converted array.
1907 */
1908function stringToArray(string) {
1909 return hasUnicode(string)
1910 ? unicodeToArray(string)
1911 : asciiToArray(string);
1912}
1913
1914/**
1915 * Converts `value` to a string. An empty string is returned for `null`
1916 * and `undefined` values. The sign of `-0` is preserved.
1917 *
1918 * @static
1919 * @memberOf _
1920 * @since 4.0.0
1921 * @category Lang
1922 * @param {*} value The value to convert.
1923 * @returns {string} Returns the converted string.
1924 * @example
1925 *
1926 * _.toString(null);
1927 * // => ''
1928 *
1929 * _.toString(-0);
1930 * // => '-0'
1931 *
1932 * _.toString([1, 2, 3]);
1933 * // => '1,2,3'
1934 */
1935function toString(value) {
1936 return value == null ? '' : baseToString(value);
1937}
1938
1939/** Used to match leading and trailing whitespace. */
1940var reTrim = /^\s+|\s+$/g;
1941
1942/**
1943 * Removes leading and trailing whitespace or specified characters from `string`.
1944 *
1945 * @static
1946 * @memberOf _
1947 * @since 3.0.0
1948 * @category String
1949 * @param {string} [string=''] The string to trim.
1950 * @param {string} [chars=whitespace] The characters to trim.
1951 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
1952 * @returns {string} Returns the trimmed string.
1953 * @example
1954 *
1955 * _.trim(' abc ');
1956 * // => 'abc'
1957 *
1958 * _.trim('-_-abc-_-', '_-');
1959 * // => 'abc'
1960 *
1961 * _.map([' foo ', ' bar '], _.trim);
1962 * // => ['foo', 'bar']
1963 */
1964function trim(string, chars, guard) {
1965 string = toString(string);
1966 if (string && (guard || chars === undefined)) {
1967 return string.replace(reTrim, '');
1968 }
1969 if (!string || !(chars = baseToString(chars))) {
1970 return string;
1971 }
1972 var strSymbols = stringToArray(string),
1973 chrSymbols = stringToArray(chars),
1974 start = charsStartIndex(strSymbols, chrSymbols),
1975 end = charsEndIndex(strSymbols, chrSymbols) + 1;
1976
1977 return castSlice(strSymbols, start, end).join('');
1978}
1979
1980var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
1981var FN_ARG_SPLIT = /,/;
1982var FN_ARG = /(=.+)?(\s*)$/;
1983var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
1984
1985function parseParams(func) {
1986 func = func.toString().replace(STRIP_COMMENTS, '');
1987 func = func.match(FN_ARGS)[2].replace(' ', '');
1988 func = func ? func.split(FN_ARG_SPLIT) : [];
1989 func = func.map(function (arg){
1990 return trim(arg.replace(FN_ARG, ''));
1991 });
1992 return func;
1993}
1994
1995/**
1996 * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
1997 * tasks are specified as parameters to the function, after the usual callback
1998 * parameter, with the parameter names matching the names of the tasks it
1999 * depends on. This can provide even more readable task graphs which can be
2000 * easier to maintain.
2001 *
2002 * If a final callback is specified, the task results are similarly injected,
2003 * specified as named parameters after the initial error parameter.
2004 *
2005 * The autoInject function is purely syntactic sugar and its semantics are
2006 * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
2007 *
2008 * @name autoInject
2009 * @static
2010 * @memberOf module:ControlFlow
2011 * @method
2012 * @see [async.auto]{@link module:ControlFlow.auto}
2013 * @category Control Flow
2014 * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
2015 * the form 'func([dependencies...], callback). The object's key of a property
2016 * serves as the name of the task defined by that property, i.e. can be used
2017 * when specifying requirements for other tasks.
2018 * * The `callback` parameter is a `callback(err, result)` which must be called
2019 * when finished, passing an `error` (which can be `null`) and the result of
2020 * the function's execution. The remaining parameters name other tasks on
2021 * which the task is dependent, and the results from those tasks are the
2022 * arguments of those parameters.
2023 * @param {Function} [callback] - An optional callback which is called when all
2024 * the tasks have been completed. It receives the `err` argument if any `tasks`
2025 * pass an error to their callback, and a `results` object with any completed
2026 * task results, similar to `auto`.
2027 * @example
2028 *
2029 * // The example from `auto` can be rewritten as follows:
2030 * async.autoInject({
2031 * get_data: function(callback) {
2032 * // async code to get some data
2033 * callback(null, 'data', 'converted to array');
2034 * },
2035 * make_folder: function(callback) {
2036 * // async code to create a directory to store a file in
2037 * // this is run at the same time as getting the data
2038 * callback(null, 'folder');
2039 * },
2040 * write_file: function(get_data, make_folder, callback) {
2041 * // once there is some data and the directory exists,
2042 * // write the data to a file in the directory
2043 * callback(null, 'filename');
2044 * },
2045 * email_link: function(write_file, callback) {
2046 * // once the file is written let's email a link to it...
2047 * // write_file contains the filename returned by write_file.
2048 * callback(null, {'file':write_file, 'email':'user@example.com'});
2049 * }
2050 * }, function(err, results) {
2051 * console.log('err = ', err);
2052 * console.log('email_link = ', results.email_link);
2053 * });
2054 *
2055 * // If you are using a JS minifier that mangles parameter names, `autoInject`
2056 * // will not work with plain functions, since the parameter names will be
2057 * // collapsed to a single letter identifier. To work around this, you can
2058 * // explicitly specify the names of the parameters your task function needs
2059 * // in an array, similar to Angular.js dependency injection.
2060 *
2061 * // This still has an advantage over plain `auto`, since the results a task
2062 * // depends on are still spread into arguments.
2063 * async.autoInject({
2064 * //...
2065 * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
2066 * callback(null, 'filename');
2067 * }],
2068 * email_link: ['write_file', function(write_file, callback) {
2069 * callback(null, {'file':write_file, 'email':'user@example.com'});
2070 * }]
2071 * //...
2072 * }, function(err, results) {
2073 * console.log('err = ', err);
2074 * console.log('email_link = ', results.email_link);
2075 * });
2076 */
2077function autoInject(tasks, callback) {
2078 var newTasks = {};
2079
2080 baseForOwn(tasks, function (taskFn, key) {
2081 var params;
2082 var fnIsAsync = isAsync(taskFn);
2083 var hasNoDeps =
2084 (!fnIsAsync && taskFn.length === 1) ||
2085 (fnIsAsync && taskFn.length === 0);
2086
2087 if (isArray(taskFn)) {
2088 params = taskFn.slice(0, -1);
2089 taskFn = taskFn[taskFn.length - 1];
2090
2091 newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
2092 } else if (hasNoDeps) {
2093 // no dependencies, use the function as-is
2094 newTasks[key] = taskFn;
2095 } else {
2096 params = parseParams(taskFn);
2097 if (taskFn.length === 0 && !fnIsAsync && params.length === 0) {
2098 throw new Error("autoInject task functions require explicit parameters.");
2099 }
2100
2101 // remove callback param
2102 if (!fnIsAsync) params.pop();
2103
2104 newTasks[key] = params.concat(newTask);
2105 }
2106
2107 function newTask(results, taskCb) {
2108 var newArgs = arrayMap(params, function (name) {
2109 return results[name];
2110 });
2111 newArgs.push(taskCb);
2112 wrapAsync(taskFn).apply(null, newArgs);
2113 }
2114 });
2115
2116 auto(newTasks, callback);
2117}
2118
2119// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
2120// used for queues. This implementation assumes that the node provided by the user can be modified
2121// to adjust the next and last properties. We implement only the minimal functionality
2122// for queue support.
2123function DLL() {
2124 this.head = this.tail = null;
2125 this.length = 0;
2126}
2127
2128function setInitial(dll, node) {
2129 dll.length = 1;
2130 dll.head = dll.tail = node;
2131}
2132
2133DLL.prototype.removeLink = function(node) {
2134 if (node.prev) node.prev.next = node.next;
2135 else this.head = node.next;
2136 if (node.next) node.next.prev = node.prev;
2137 else this.tail = node.prev;
2138
2139 node.prev = node.next = null;
2140 this.length -= 1;
2141 return node;
2142};
2143
2144DLL.prototype.empty = function () {
2145 while(this.head) this.shift();
2146 return this;
2147};
2148
2149DLL.prototype.insertAfter = function(node, newNode) {
2150 newNode.prev = node;
2151 newNode.next = node.next;
2152 if (node.next) node.next.prev = newNode;
2153 else this.tail = newNode;
2154 node.next = newNode;
2155 this.length += 1;
2156};
2157
2158DLL.prototype.insertBefore = function(node, newNode) {
2159 newNode.prev = node.prev;
2160 newNode.next = node;
2161 if (node.prev) node.prev.next = newNode;
2162 else this.head = newNode;
2163 node.prev = newNode;
2164 this.length += 1;
2165};
2166
2167DLL.prototype.unshift = function(node) {
2168 if (this.head) this.insertBefore(this.head, node);
2169 else setInitial(this, node);
2170};
2171
2172DLL.prototype.push = function(node) {
2173 if (this.tail) this.insertAfter(this.tail, node);
2174 else setInitial(this, node);
2175};
2176
2177DLL.prototype.shift = function() {
2178 return this.head && this.removeLink(this.head);
2179};
2180
2181DLL.prototype.pop = function() {
2182 return this.tail && this.removeLink(this.tail);
2183};
2184
2185DLL.prototype.toArray = function () {
2186 var arr = Array(this.length);
2187 var curr = this.head;
2188 for(var idx = 0; idx < this.length; idx++) {
2189 arr[idx] = curr.data;
2190 curr = curr.next;
2191 }
2192 return arr;
2193};
2194
2195DLL.prototype.remove = function (testFn) {
2196 var curr = this.head;
2197 while(!!curr) {
2198 var next = curr.next;
2199 if (testFn(curr)) {
2200 this.removeLink(curr);
2201 }
2202 curr = next;
2203 }
2204 return this;
2205};
2206
2207function queue(worker, concurrency, payload) {
2208 if (concurrency == null) {
2209 concurrency = 1;
2210 }
2211 else if(concurrency === 0) {
2212 throw new Error('Concurrency must not be zero');
2213 }
2214
2215 var _worker = wrapAsync(worker);
2216 var numRunning = 0;
2217 var workersList = [];
2218
2219 var processingScheduled = false;
2220 function _insert(data, insertAtFront, callback) {
2221 if (callback != null && typeof callback !== 'function') {
2222 throw new Error('task callback must be a function');
2223 }
2224 q.started = true;
2225 if (!isArray(data)) {
2226 data = [data];
2227 }
2228 if (data.length === 0 && q.idle()) {
2229 // call drain immediately if there are no tasks
2230 return setImmediate$1(function() {
2231 q.drain();
2232 });
2233 }
2234
2235 for (var i = 0, l = data.length; i < l; i++) {
2236 var item = {
2237 data: data[i],
2238 callback: callback || noop
2239 };
2240
2241 if (insertAtFront) {
2242 q._tasks.unshift(item);
2243 } else {
2244 q._tasks.push(item);
2245 }
2246 }
2247
2248 if (!processingScheduled) {
2249 processingScheduled = true;
2250 setImmediate$1(function() {
2251 processingScheduled = false;
2252 q.process();
2253 });
2254 }
2255 }
2256
2257 function _next(tasks) {
2258 return function(err){
2259 numRunning -= 1;
2260
2261 for (var i = 0, l = tasks.length; i < l; i++) {
2262 var task = tasks[i];
2263
2264 var index = baseIndexOf(workersList, task, 0);
2265 if (index === 0) {
2266 workersList.shift();
2267 } else if (index > 0) {
2268 workersList.splice(index, 1);
2269 }
2270
2271 task.callback.apply(task, arguments);
2272
2273 if (err != null) {
2274 q.error(err, task.data);
2275 }
2276 }
2277
2278 if (numRunning <= (q.concurrency - q.buffer) ) {
2279 q.unsaturated();
2280 }
2281
2282 if (q.idle()) {
2283 q.drain();
2284 }
2285 q.process();
2286 };
2287 }
2288
2289 var isProcessing = false;
2290 var q = {
2291 _tasks: new DLL(),
2292 concurrency: concurrency,
2293 payload: payload,
2294 saturated: noop,
2295 unsaturated:noop,
2296 buffer: concurrency / 4,
2297 empty: noop,
2298 drain: noop,
2299 error: noop,
2300 started: false,
2301 paused: false,
2302 push: function (data, callback) {
2303 _insert(data, false, callback);
2304 },
2305 kill: function () {
2306 q.drain = noop;
2307 q._tasks.empty();
2308 },
2309 unshift: function (data, callback) {
2310 _insert(data, true, callback);
2311 },
2312 remove: function (testFn) {
2313 q._tasks.remove(testFn);
2314 },
2315 process: function () {
2316 // Avoid trying to start too many processing operations. This can occur
2317 // when callbacks resolve synchronously (#1267).
2318 if (isProcessing) {
2319 return;
2320 }
2321 isProcessing = true;
2322 while(!q.paused && numRunning < q.concurrency && q._tasks.length){
2323 var tasks = [], data = [];
2324 var l = q._tasks.length;
2325 if (q.payload) l = Math.min(l, q.payload);
2326 for (var i = 0; i < l; i++) {
2327 var node = q._tasks.shift();
2328 tasks.push(node);
2329 workersList.push(node);
2330 data.push(node.data);
2331 }
2332
2333 numRunning += 1;
2334
2335 if (q._tasks.length === 0) {
2336 q.empty();
2337 }
2338
2339 if (numRunning === q.concurrency) {
2340 q.saturated();
2341 }
2342
2343 var cb = onlyOnce(_next(tasks));
2344 _worker(data, cb);
2345 }
2346 isProcessing = false;
2347 },
2348 length: function () {
2349 return q._tasks.length;
2350 },
2351 running: function () {
2352 return numRunning;
2353 },
2354 workersList: function () {
2355 return workersList;
2356 },
2357 idle: function() {
2358 return q._tasks.length + numRunning === 0;
2359 },
2360 pause: function () {
2361 q.paused = true;
2362 },
2363 resume: function () {
2364 if (q.paused === false) { return; }
2365 q.paused = false;
2366 setImmediate$1(q.process);
2367 }
2368 };
2369 return q;
2370}
2371
2372/**
2373 * A cargo of tasks for the worker function to complete. Cargo inherits all of
2374 * the same methods and event callbacks as [`queue`]{@link module:ControlFlow.queue}.
2375 * @typedef {Object} CargoObject
2376 * @memberOf module:ControlFlow
2377 * @property {Function} length - A function returning the number of items
2378 * waiting to be processed. Invoke like `cargo.length()`.
2379 * @property {number} payload - An `integer` for determining how many tasks
2380 * should be process per round. This property can be changed after a `cargo` is
2381 * created to alter the payload on-the-fly.
2382 * @property {Function} push - Adds `task` to the `queue`. The callback is
2383 * called once the `worker` has finished processing the task. Instead of a
2384 * single task, an array of `tasks` can be submitted. The respective callback is
2385 * used for every task in the list. Invoke like `cargo.push(task, [callback])`.
2386 * @property {Function} saturated - A callback that is called when the
2387 * `queue.length()` hits the concurrency and further tasks will be queued.
2388 * @property {Function} empty - A callback that is called when the last item
2389 * from the `queue` is given to a `worker`.
2390 * @property {Function} drain - A callback that is called when the last item
2391 * from the `queue` has returned from the `worker`.
2392 * @property {Function} idle - a function returning false if there are items
2393 * waiting or being processed, or true if not. Invoke like `cargo.idle()`.
2394 * @property {Function} pause - a function that pauses the processing of tasks
2395 * until `resume()` is called. Invoke like `cargo.pause()`.
2396 * @property {Function} resume - a function that resumes the processing of
2397 * queued tasks when the queue is paused. Invoke like `cargo.resume()`.
2398 * @property {Function} kill - a function that removes the `drain` callback and
2399 * empties remaining tasks from the queue forcing it to go idle. Invoke like `cargo.kill()`.
2400 */
2401
2402/**
2403 * Creates a `cargo` object with the specified payload. Tasks added to the
2404 * cargo will be processed altogether (up to the `payload` limit). If the
2405 * `worker` is in progress, the task is queued until it becomes available. Once
2406 * the `worker` has completed some tasks, each callback of those tasks is
2407 * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
2408 * for how `cargo` and `queue` work.
2409 *
2410 * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
2411 * at a time, cargo passes an array of tasks to a single worker, repeating
2412 * when the worker is finished.
2413 *
2414 * @name cargo
2415 * @static
2416 * @memberOf module:ControlFlow
2417 * @method
2418 * @see [async.queue]{@link module:ControlFlow.queue}
2419 * @category Control Flow
2420 * @param {AsyncFunction} worker - An asynchronous function for processing an array
2421 * of queued tasks. Invoked with `(tasks, callback)`.
2422 * @param {number} [payload=Infinity] - An optional `integer` for determining
2423 * how many tasks should be processed per round; if omitted, the default is
2424 * unlimited.
2425 * @returns {module:ControlFlow.CargoObject} A cargo object to manage the tasks. Callbacks can
2426 * attached as certain properties to listen for specific events during the
2427 * lifecycle of the cargo and inner queue.
2428 * @example
2429 *
2430 * // create a cargo object with payload 2
2431 * var cargo = async.cargo(function(tasks, callback) {
2432 * for (var i=0; i<tasks.length; i++) {
2433 * console.log('hello ' + tasks[i].name);
2434 * }
2435 * callback();
2436 * }, 2);
2437 *
2438 * // add some items
2439 * cargo.push({name: 'foo'}, function(err) {
2440 * console.log('finished processing foo');
2441 * });
2442 * cargo.push({name: 'bar'}, function(err) {
2443 * console.log('finished processing bar');
2444 * });
2445 * cargo.push({name: 'baz'}, function(err) {
2446 * console.log('finished processing baz');
2447 * });
2448 */
2449function cargo(worker, payload) {
2450 return queue(worker, 1, payload);
2451}
2452
2453/**
2454 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
2455 *
2456 * @name eachOfSeries
2457 * @static
2458 * @memberOf module:Collections
2459 * @method
2460 * @see [async.eachOf]{@link module:Collections.eachOf}
2461 * @alias forEachOfSeries
2462 * @category Collection
2463 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2464 * @param {AsyncFunction} iteratee - An async function to apply to each item in
2465 * `coll`.
2466 * Invoked with (item, key, callback).
2467 * @param {Function} [callback] - A callback which is called when all `iteratee`
2468 * functions have finished, or an error occurs. Invoked with (err).
2469 */
2470var eachOfSeries = doLimit(eachOfLimit, 1);
2471
2472/**
2473 * Reduces `coll` into a single value using an async `iteratee` to return each
2474 * successive step. `memo` is the initial state of the reduction. This function
2475 * only operates in series.
2476 *
2477 * For performance reasons, it may make sense to split a call to this function
2478 * into a parallel map, and then use the normal `Array.prototype.reduce` on the
2479 * results. This function is for situations where each step in the reduction
2480 * needs to be async; if you can get the data before reducing it, then it's
2481 * probably a good idea to do so.
2482 *
2483 * @name reduce
2484 * @static
2485 * @memberOf module:Collections
2486 * @method
2487 * @alias inject
2488 * @alias foldl
2489 * @category Collection
2490 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2491 * @param {*} memo - The initial state of the reduction.
2492 * @param {AsyncFunction} iteratee - A function applied to each item in the
2493 * array to produce the next step in the reduction.
2494 * The `iteratee` should complete with the next state of the reduction.
2495 * If the iteratee complete with an error, the reduction is stopped and the
2496 * main `callback` is immediately called with the error.
2497 * Invoked with (memo, item, callback).
2498 * @param {Function} [callback] - A callback which is called after all the
2499 * `iteratee` functions have finished. Result is the reduced value. Invoked with
2500 * (err, result).
2501 * @example
2502 *
2503 * async.reduce([1,2,3], 0, function(memo, item, callback) {
2504 * // pointless async:
2505 * process.nextTick(function() {
2506 * callback(null, memo + item)
2507 * });
2508 * }, function(err, result) {
2509 * // result is now equal to the last value of memo, which is 6
2510 * });
2511 */
2512function reduce(coll, memo, iteratee, callback) {
2513 callback = once(callback || noop);
2514 var _iteratee = wrapAsync(iteratee);
2515 eachOfSeries(coll, function(x, i, callback) {
2516 _iteratee(memo, x, function(err, v) {
2517 memo = v;
2518 callback(err);
2519 });
2520 }, function(err) {
2521 callback(err, memo);
2522 });
2523}
2524
2525/**
2526 * Version of the compose function that is more natural to read. Each function
2527 * consumes the return value of the previous function. It is the equivalent of
2528 * [compose]{@link module:ControlFlow.compose} with the arguments reversed.
2529 *
2530 * Each function is executed with the `this` binding of the composed function.
2531 *
2532 * @name seq
2533 * @static
2534 * @memberOf module:ControlFlow
2535 * @method
2536 * @see [async.compose]{@link module:ControlFlow.compose}
2537 * @category Control Flow
2538 * @param {...AsyncFunction} functions - the asynchronous functions to compose
2539 * @returns {Function} a function that composes the `functions` in order
2540 * @example
2541 *
2542 * // Requires lodash (or underscore), express3 and dresende's orm2.
2543 * // Part of an app, that fetches cats of the logged user.
2544 * // This example uses `seq` function to avoid overnesting and error
2545 * // handling clutter.
2546 * app.get('/cats', function(request, response) {
2547 * var User = request.models.User;
2548 * async.seq(
2549 * _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data))
2550 * function(user, fn) {
2551 * user.getCats(fn); // 'getCats' has signature (callback(err, data))
2552 * }
2553 * )(req.session.user_id, function (err, cats) {
2554 * if (err) {
2555 * console.error(err);
2556 * response.json({ status: 'error', message: err.message });
2557 * } else {
2558 * response.json({ status: 'ok', message: 'Cats found', data: cats });
2559 * }
2560 * });
2561 * });
2562 */
2563function seq(/*...functions*/) {
2564 var _functions = arrayMap(arguments, wrapAsync);
2565 return function(/*...args*/) {
2566 var args = slice(arguments);
2567 var that = this;
2568
2569 var cb = args[args.length - 1];
2570 if (typeof cb == 'function') {
2571 args.pop();
2572 } else {
2573 cb = noop;
2574 }
2575
2576 reduce(_functions, args, function(newargs, fn, cb) {
2577 fn.apply(that, newargs.concat(function(err/*, ...nextargs*/) {
2578 var nextargs = slice(arguments, 1);
2579 cb(err, nextargs);
2580 }));
2581 },
2582 function(err, results) {
2583 cb.apply(that, [err].concat(results));
2584 });
2585 };
2586}
2587
2588/**
2589 * Creates a function which is a composition of the passed asynchronous
2590 * functions. Each function consumes the return value of the function that
2591 * follows. Composing functions `f()`, `g()`, and `h()` would produce the result
2592 * of `f(g(h()))`, only this version uses callbacks to obtain the return values.
2593 *
2594 * Each function is executed with the `this` binding of the composed function.
2595 *
2596 * @name compose
2597 * @static
2598 * @memberOf module:ControlFlow
2599 * @method
2600 * @category Control Flow
2601 * @param {...AsyncFunction} functions - the asynchronous functions to compose
2602 * @returns {Function} an asynchronous function that is the composed
2603 * asynchronous `functions`
2604 * @example
2605 *
2606 * function add1(n, callback) {
2607 * setTimeout(function () {
2608 * callback(null, n + 1);
2609 * }, 10);
2610 * }
2611 *
2612 * function mul3(n, callback) {
2613 * setTimeout(function () {
2614 * callback(null, n * 3);
2615 * }, 10);
2616 * }
2617 *
2618 * var add1mul3 = async.compose(mul3, add1);
2619 * add1mul3(4, function (err, result) {
2620 * // result now equals 15
2621 * });
2622 */
2623var compose = function(/*...args*/) {
2624 return seq.apply(null, slice(arguments).reverse());
2625};
2626
2627var _concat = Array.prototype.concat;
2628
2629/**
2630 * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
2631 *
2632 * @name concatLimit
2633 * @static
2634 * @memberOf module:Collections
2635 * @method
2636 * @see [async.concat]{@link module:Collections.concat}
2637 * @category Collection
2638 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2639 * @param {number} limit - The maximum number of async operations at a time.
2640 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
2641 * which should use an array as its result. Invoked with (item, callback).
2642 * @param {Function} [callback] - A callback which is called after all the
2643 * `iteratee` functions have finished, or an error occurs. Results is an array
2644 * containing the concatenated results of the `iteratee` function. Invoked with
2645 * (err, results).
2646 */
2647var concatLimit = function(coll, limit, iteratee, callback) {
2648 callback = callback || noop;
2649 var _iteratee = wrapAsync(iteratee);
2650 mapLimit(coll, limit, function(val, callback) {
2651 _iteratee(val, function(err /*, ...args*/) {
2652 if (err) return callback(err);
2653 return callback(null, slice(arguments, 1));
2654 });
2655 }, function(err, mapResults) {
2656 var result = [];
2657 for (var i = 0; i < mapResults.length; i++) {
2658 if (mapResults[i]) {
2659 result = _concat.apply(result, mapResults[i]);
2660 }
2661 }
2662
2663 return callback(err, result);
2664 });
2665};
2666
2667/**
2668 * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
2669 * the concatenated list. The `iteratee`s are called in parallel, and the
2670 * results are concatenated as they return. There is no guarantee that the
2671 * results array will be returned in the original order of `coll` passed to the
2672 * `iteratee` function.
2673 *
2674 * @name concat
2675 * @static
2676 * @memberOf module:Collections
2677 * @method
2678 * @category Collection
2679 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2680 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
2681 * which should use an array as its result. Invoked with (item, callback).
2682 * @param {Function} [callback(err)] - A callback which is called after all the
2683 * `iteratee` functions have finished, or an error occurs. Results is an array
2684 * containing the concatenated results of the `iteratee` function. Invoked with
2685 * (err, results).
2686 * @example
2687 *
2688 * async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) {
2689 * // files is now a list of filenames that exist in the 3 directories
2690 * });
2691 */
2692var concat = doLimit(concatLimit, Infinity);
2693
2694/**
2695 * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
2696 *
2697 * @name concatSeries
2698 * @static
2699 * @memberOf module:Collections
2700 * @method
2701 * @see [async.concat]{@link module:Collections.concat}
2702 * @category Collection
2703 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2704 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
2705 * The iteratee should complete with an array an array of results.
2706 * Invoked with (item, callback).
2707 * @param {Function} [callback(err)] - A callback which is called after all the
2708 * `iteratee` functions have finished, or an error occurs. Results is an array
2709 * containing the concatenated results of the `iteratee` function. Invoked with
2710 * (err, results).
2711 */
2712var concatSeries = doLimit(concatLimit, 1);
2713
2714/**
2715 * Returns a function that when called, calls-back with the values provided.
2716 * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
2717 * [`auto`]{@link module:ControlFlow.auto}.
2718 *
2719 * @name constant
2720 * @static
2721 * @memberOf module:Utils
2722 * @method
2723 * @category Util
2724 * @param {...*} arguments... - Any number of arguments to automatically invoke
2725 * callback with.
2726 * @returns {AsyncFunction} Returns a function that when invoked, automatically
2727 * invokes the callback with the previous given arguments.
2728 * @example
2729 *
2730 * async.waterfall([
2731 * async.constant(42),
2732 * function (value, next) {
2733 * // value === 42
2734 * },
2735 * //...
2736 * ], callback);
2737 *
2738 * async.waterfall([
2739 * async.constant(filename, "utf8"),
2740 * fs.readFile,
2741 * function (fileData, next) {
2742 * //...
2743 * }
2744 * //...
2745 * ], callback);
2746 *
2747 * async.auto({
2748 * hostname: async.constant("https://server.net/"),
2749 * port: findFreePort,
2750 * launchServer: ["hostname", "port", function (options, cb) {
2751 * startServer(options, cb);
2752 * }],
2753 * //...
2754 * }, callback);
2755 */
2756var constant = function(/*...values*/) {
2757 var values = slice(arguments);
2758 var args = [null].concat(values);
2759 return function (/*...ignoredArgs, callback*/) {
2760 var callback = arguments[arguments.length - 1];
2761 return callback.apply(this, args);
2762 };
2763};
2764
2765/**
2766 * This method returns the first argument it receives.
2767 *
2768 * @static
2769 * @since 0.1.0
2770 * @memberOf _
2771 * @category Util
2772 * @param {*} value Any value.
2773 * @returns {*} Returns `value`.
2774 * @example
2775 *
2776 * var object = { 'a': 1 };
2777 *
2778 * console.log(_.identity(object) === object);
2779 * // => true
2780 */
2781function identity(value) {
2782 return value;
2783}
2784
2785function _createTester(check, getResult) {
2786 return function(eachfn, arr, iteratee, cb) {
2787 cb = cb || noop;
2788 var testPassed = false;
2789 var testResult;
2790 eachfn(arr, function(value, _, callback) {
2791 iteratee(value, function(err, result) {
2792 if (err) {
2793 callback(err);
2794 } else if (check(result) && !testResult) {
2795 testPassed = true;
2796 testResult = getResult(true, value);
2797 callback(null, breakLoop);
2798 } else {
2799 callback();
2800 }
2801 });
2802 }, function(err) {
2803 if (err) {
2804 cb(err);
2805 } else {
2806 cb(null, testPassed ? testResult : getResult(false));
2807 }
2808 });
2809 };
2810}
2811
2812function _findGetResult(v, x) {
2813 return x;
2814}
2815
2816/**
2817 * Returns the first value in `coll` that passes an async truth test. The
2818 * `iteratee` is applied in parallel, meaning the first iteratee to return
2819 * `true` will fire the detect `callback` with that result. That means the
2820 * result might not be the first item in the original `coll` (in terms of order)
2821 * that passes the test.
2822
2823 * If order within the original `coll` is important, then look at
2824 * [`detectSeries`]{@link module:Collections.detectSeries}.
2825 *
2826 * @name detect
2827 * @static
2828 * @memberOf module:Collections
2829 * @method
2830 * @alias find
2831 * @category Collections
2832 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2833 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2834 * The iteratee must complete with a boolean value as its result.
2835 * Invoked with (item, callback).
2836 * @param {Function} [callback] - A callback which is called as soon as any
2837 * iteratee returns `true`, or after all the `iteratee` functions have finished.
2838 * Result will be the first item in the array that passes the truth test
2839 * (iteratee) or the value `undefined` if none passed. Invoked with
2840 * (err, result).
2841 * @example
2842 *
2843 * async.detect(['file1','file2','file3'], function(filePath, callback) {
2844 * fs.access(filePath, function(err) {
2845 * callback(null, !err)
2846 * });
2847 * }, function(err, result) {
2848 * // result now equals the first file in the list that exists
2849 * });
2850 */
2851var detect = doParallel(_createTester(identity, _findGetResult));
2852
2853/**
2854 * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
2855 * time.
2856 *
2857 * @name detectLimit
2858 * @static
2859 * @memberOf module:Collections
2860 * @method
2861 * @see [async.detect]{@link module:Collections.detect}
2862 * @alias findLimit
2863 * @category Collections
2864 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2865 * @param {number} limit - The maximum number of async operations at a time.
2866 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2867 * The iteratee must complete with a boolean value as its result.
2868 * Invoked with (item, callback).
2869 * @param {Function} [callback] - A callback which is called as soon as any
2870 * iteratee returns `true`, or after all the `iteratee` functions have finished.
2871 * Result will be the first item in the array that passes the truth test
2872 * (iteratee) or the value `undefined` if none passed. Invoked with
2873 * (err, result).
2874 */
2875var detectLimit = doParallelLimit(_createTester(identity, _findGetResult));
2876
2877/**
2878 * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
2879 *
2880 * @name detectSeries
2881 * @static
2882 * @memberOf module:Collections
2883 * @method
2884 * @see [async.detect]{@link module:Collections.detect}
2885 * @alias findSeries
2886 * @category Collections
2887 * @param {Array|Iterable|Object} coll - A collection to iterate over.
2888 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2889 * The iteratee must complete with a boolean value as its result.
2890 * Invoked with (item, callback).
2891 * @param {Function} [callback] - A callback which is called as soon as any
2892 * iteratee returns `true`, or after all the `iteratee` functions have finished.
2893 * Result will be the first item in the array that passes the truth test
2894 * (iteratee) or the value `undefined` if none passed. Invoked with
2895 * (err, result).
2896 */
2897var detectSeries = doLimit(detectLimit, 1);
2898
2899function consoleFunc(name) {
2900 return function (fn/*, ...args*/) {
2901 var args = slice(arguments, 1);
2902 args.push(function (err/*, ...args*/) {
2903 var args = slice(arguments, 1);
2904 if (typeof console === 'object') {
2905 if (err) {
2906 if (console.error) {
2907 console.error(err);
2908 }
2909 } else if (console[name]) {
2910 arrayEach(args, function (x) {
2911 console[name](x);
2912 });
2913 }
2914 }
2915 });
2916 wrapAsync(fn).apply(null, args);
2917 };
2918}
2919
2920/**
2921 * Logs the result of an [`async` function]{@link AsyncFunction} to the
2922 * `console` using `console.dir` to display the properties of the resulting object.
2923 * Only works in Node.js or in browsers that support `console.dir` and
2924 * `console.error` (such as FF and Chrome).
2925 * If multiple arguments are returned from the async function,
2926 * `console.dir` is called on each argument in order.
2927 *
2928 * @name dir
2929 * @static
2930 * @memberOf module:Utils
2931 * @method
2932 * @category Util
2933 * @param {AsyncFunction} function - The function you want to eventually apply
2934 * all arguments to.
2935 * @param {...*} arguments... - Any number of arguments to apply to the function.
2936 * @example
2937 *
2938 * // in a module
2939 * var hello = function(name, callback) {
2940 * setTimeout(function() {
2941 * callback(null, {hello: name});
2942 * }, 1000);
2943 * };
2944 *
2945 * // in the node repl
2946 * node> async.dir(hello, 'world');
2947 * {hello: 'world'}
2948 */
2949var dir = consoleFunc('dir');
2950
2951/**
2952 * The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in
2953 * the order of operations, the arguments `test` and `fn` are switched.
2954 *
2955 * Also a version of [`doWhilst`]{@link module:ControlFlow.doWhilst} with asynchronous `test` function.
2956 * @name doDuring
2957 * @static
2958 * @memberOf module:ControlFlow
2959 * @method
2960 * @see [async.during]{@link module:ControlFlow.during}
2961 * @category Control Flow
2962 * @param {AsyncFunction} fn - An async function which is called each time
2963 * `test` passes. Invoked with (callback).
2964 * @param {AsyncFunction} test - asynchronous truth test to perform before each
2965 * execution of `fn`. Invoked with (...args, callback), where `...args` are the
2966 * non-error args from the previous callback of `fn`.
2967 * @param {Function} [callback] - A callback which is called after the test
2968 * function has failed and repeated execution of `fn` has stopped. `callback`
2969 * will be passed an error if one occurred, otherwise `null`.
2970 */
2971function doDuring(fn, test, callback) {
2972 callback = onlyOnce(callback || noop);
2973 var _fn = wrapAsync(fn);
2974 var _test = wrapAsync(test);
2975
2976 function next(err/*, ...args*/) {
2977 if (err) return callback(err);
2978 var args = slice(arguments, 1);
2979 args.push(check);
2980 _test.apply(this, args);
2981 }
2982
2983 function check(err, truth) {
2984 if (err) return callback(err);
2985 if (!truth) return callback(null);
2986 _fn(next);
2987 }
2988
2989 check(null, true);
2990
2991}
2992
2993/**
2994 * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
2995 * the order of operations, the arguments `test` and `iteratee` are switched.
2996 *
2997 * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
2998 *
2999 * @name doWhilst
3000 * @static
3001 * @memberOf module:ControlFlow
3002 * @method
3003 * @see [async.whilst]{@link module:ControlFlow.whilst}
3004 * @category Control Flow
3005 * @param {AsyncFunction} iteratee - A function which is called each time `test`
3006 * passes. Invoked with (callback).
3007 * @param {Function} test - synchronous truth test to perform after each
3008 * execution of `iteratee`. Invoked with any non-error callback results of
3009 * `iteratee`.
3010 * @param {Function} [callback] - A callback which is called after the test
3011 * function has failed and repeated execution of `iteratee` has stopped.
3012 * `callback` will be passed an error and any arguments passed to the final
3013 * `iteratee`'s callback. Invoked with (err, [results]);
3014 */
3015function doWhilst(iteratee, test, callback) {
3016 callback = onlyOnce(callback || noop);
3017 var _iteratee = wrapAsync(iteratee);
3018 var next = function(err/*, ...args*/) {
3019 if (err) return callback(err);
3020 var args = slice(arguments, 1);
3021 if (test.apply(this, args)) return _iteratee(next);
3022 callback.apply(null, [null].concat(args));
3023 };
3024 _iteratee(next);
3025}
3026
3027/**
3028 * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
3029 * argument ordering differs from `until`.
3030 *
3031 * @name doUntil
3032 * @static
3033 * @memberOf module:ControlFlow
3034 * @method
3035 * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
3036 * @category Control Flow
3037 * @param {AsyncFunction} iteratee - An async function which is called each time
3038 * `test` fails. Invoked with (callback).
3039 * @param {Function} test - synchronous truth test to perform after each
3040 * execution of `iteratee`. Invoked with any non-error callback results of
3041 * `iteratee`.
3042 * @param {Function} [callback] - A callback which is called after the test
3043 * function has passed and repeated execution of `iteratee` has stopped. `callback`
3044 * will be passed an error and any arguments passed to the final `iteratee`'s
3045 * callback. Invoked with (err, [results]);
3046 */
3047function doUntil(iteratee, test, callback) {
3048 doWhilst(iteratee, function() {
3049 return !test.apply(this, arguments);
3050 }, callback);
3051}
3052
3053/**
3054 * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that
3055 * is passed a callback in the form of `function (err, truth)`. If error is
3056 * passed to `test` or `fn`, the main callback is immediately called with the
3057 * value of the error.
3058 *
3059 * @name during
3060 * @static
3061 * @memberOf module:ControlFlow
3062 * @method
3063 * @see [async.whilst]{@link module:ControlFlow.whilst}
3064 * @category Control Flow
3065 * @param {AsyncFunction} test - asynchronous truth test to perform before each
3066 * execution of `fn`. Invoked with (callback).
3067 * @param {AsyncFunction} fn - An async function which is called each time
3068 * `test` passes. Invoked with (callback).
3069 * @param {Function} [callback] - A callback which is called after the test
3070 * function has failed and repeated execution of `fn` has stopped. `callback`
3071 * will be passed an error, if one occurred, otherwise `null`.
3072 * @example
3073 *
3074 * var count = 0;
3075 *
3076 * async.during(
3077 * function (callback) {
3078 * return callback(null, count < 5);
3079 * },
3080 * function (callback) {
3081 * count++;
3082 * setTimeout(callback, 1000);
3083 * },
3084 * function (err) {
3085 * // 5 seconds have passed
3086 * }
3087 * );
3088 */
3089function during(test, fn, callback) {
3090 callback = onlyOnce(callback || noop);
3091 var _fn = wrapAsync(fn);
3092 var _test = wrapAsync(test);
3093
3094 function next(err) {
3095 if (err) return callback(err);
3096 _test(check);
3097 }
3098
3099 function check(err, truth) {
3100 if (err) return callback(err);
3101 if (!truth) return callback(null);
3102 _fn(next);
3103 }
3104
3105 _test(check);
3106}
3107
3108function _withoutIndex(iteratee) {
3109 return function (value, index, callback) {
3110 return iteratee(value, callback);
3111 };
3112}
3113
3114/**
3115 * Applies the function `iteratee` to each item in `coll`, in parallel.
3116 * The `iteratee` is called with an item from the list, and a callback for when
3117 * it has finished. If the `iteratee` passes an error to its `callback`, the
3118 * main `callback` (for the `each` function) is immediately called with the
3119 * error.
3120 *
3121 * Note, that since this function applies `iteratee` to each item in parallel,
3122 * there is no guarantee that the iteratee functions will complete in order.
3123 *
3124 * @name each
3125 * @static
3126 * @memberOf module:Collections
3127 * @method
3128 * @alias forEach
3129 * @category Collection
3130 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3131 * @param {AsyncFunction} iteratee - An async function to apply to
3132 * each item in `coll`. Invoked with (item, callback).
3133 * The array index is not passed to the iteratee.
3134 * If you need the index, use `eachOf`.
3135 * @param {Function} [callback] - A callback which is called when all
3136 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
3137 * @example
3138 *
3139 * // assuming openFiles is an array of file names and saveFile is a function
3140 * // to save the modified contents of that file:
3141 *
3142 * async.each(openFiles, saveFile, function(err){
3143 * // if any of the saves produced an error, err would equal that error
3144 * });
3145 *
3146 * // assuming openFiles is an array of file names
3147 * async.each(openFiles, function(file, callback) {
3148 *
3149 * // Perform operation on file here.
3150 * console.log('Processing file ' + file);
3151 *
3152 * if( file.length > 32 ) {
3153 * console.log('This file name is too long');
3154 * callback('File name too long');
3155 * } else {
3156 * // Do work to process file here
3157 * console.log('File processed');
3158 * callback();
3159 * }
3160 * }, function(err) {
3161 * // if any of the file processing produced an error, err would equal that error
3162 * if( err ) {
3163 * // One of the iterations produced an error.
3164 * // All processing will now stop.
3165 * console.log('A file failed to process');
3166 * } else {
3167 * console.log('All files have been processed successfully');
3168 * }
3169 * });
3170 */
3171function eachLimit(coll, iteratee, callback) {
3172 eachOf(coll, _withoutIndex(wrapAsync(iteratee)), callback);
3173}
3174
3175/**
3176 * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
3177 *
3178 * @name eachLimit
3179 * @static
3180 * @memberOf module:Collections
3181 * @method
3182 * @see [async.each]{@link module:Collections.each}
3183 * @alias forEachLimit
3184 * @category Collection
3185 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3186 * @param {number} limit - The maximum number of async operations at a time.
3187 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3188 * `coll`.
3189 * The array index is not passed to the iteratee.
3190 * If you need the index, use `eachOfLimit`.
3191 * Invoked with (item, callback).
3192 * @param {Function} [callback] - A callback which is called when all
3193 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
3194 */
3195function eachLimit$1(coll, limit, iteratee, callback) {
3196 _eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
3197}
3198
3199/**
3200 * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
3201 *
3202 * @name eachSeries
3203 * @static
3204 * @memberOf module:Collections
3205 * @method
3206 * @see [async.each]{@link module:Collections.each}
3207 * @alias forEachSeries
3208 * @category Collection
3209 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3210 * @param {AsyncFunction} iteratee - An async function to apply to each
3211 * item in `coll`.
3212 * The array index is not passed to the iteratee.
3213 * If you need the index, use `eachOfSeries`.
3214 * Invoked with (item, callback).
3215 * @param {Function} [callback] - A callback which is called when all
3216 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
3217 */
3218var eachSeries = doLimit(eachLimit$1, 1);
3219
3220/**
3221 * Wrap an async function and ensure it calls its callback on a later tick of
3222 * the event loop. If the function already calls its callback on a next tick,
3223 * no extra deferral is added. This is useful for preventing stack overflows
3224 * (`RangeError: Maximum call stack size exceeded`) and generally keeping
3225 * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
3226 * contained. ES2017 `async` functions are returned as-is -- they are immune
3227 * to Zalgo's corrupting influences, as they always resolve on a later tick.
3228 *
3229 * @name ensureAsync
3230 * @static
3231 * @memberOf module:Utils
3232 * @method
3233 * @category Util
3234 * @param {AsyncFunction} fn - an async function, one that expects a node-style
3235 * callback as its last argument.
3236 * @returns {AsyncFunction} Returns a wrapped function with the exact same call
3237 * signature as the function passed in.
3238 * @example
3239 *
3240 * function sometimesAsync(arg, callback) {
3241 * if (cache[arg]) {
3242 * return callback(null, cache[arg]); // this would be synchronous!!
3243 * } else {
3244 * doSomeIO(arg, callback); // this IO would be asynchronous
3245 * }
3246 * }
3247 *
3248 * // this has a risk of stack overflows if many results are cached in a row
3249 * async.mapSeries(args, sometimesAsync, done);
3250 *
3251 * // this will defer sometimesAsync's callback if necessary,
3252 * // preventing stack overflows
3253 * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
3254 */
3255function ensureAsync(fn) {
3256 if (isAsync(fn)) return fn;
3257 return initialParams(function (args, callback) {
3258 var sync = true;
3259 args.push(function () {
3260 var innerArgs = arguments;
3261 if (sync) {
3262 setImmediate$1(function () {
3263 callback.apply(null, innerArgs);
3264 });
3265 } else {
3266 callback.apply(null, innerArgs);
3267 }
3268 });
3269 fn.apply(this, args);
3270 sync = false;
3271 });
3272}
3273
3274function notId(v) {
3275 return !v;
3276}
3277
3278/**
3279 * Returns `true` if every element in `coll` satisfies an async test. If any
3280 * iteratee call returns `false`, the main `callback` is immediately called.
3281 *
3282 * @name every
3283 * @static
3284 * @memberOf module:Collections
3285 * @method
3286 * @alias all
3287 * @category Collection
3288 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3289 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3290 * in the collection in parallel.
3291 * The iteratee must complete with a boolean result value.
3292 * Invoked with (item, callback).
3293 * @param {Function} [callback] - A callback which is called after all the
3294 * `iteratee` functions have finished. Result will be either `true` or `false`
3295 * depending on the values of the async tests. Invoked with (err, result).
3296 * @example
3297 *
3298 * async.every(['file1','file2','file3'], function(filePath, callback) {
3299 * fs.access(filePath, function(err) {
3300 * callback(null, !err)
3301 * });
3302 * }, function(err, result) {
3303 * // if result is true then every file exists
3304 * });
3305 */
3306var every = doParallel(_createTester(notId, notId));
3307
3308/**
3309 * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
3310 *
3311 * @name everyLimit
3312 * @static
3313 * @memberOf module:Collections
3314 * @method
3315 * @see [async.every]{@link module:Collections.every}
3316 * @alias allLimit
3317 * @category Collection
3318 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3319 * @param {number} limit - The maximum number of async operations at a time.
3320 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3321 * in the collection in parallel.
3322 * The iteratee must complete with a boolean result value.
3323 * Invoked with (item, callback).
3324 * @param {Function} [callback] - A callback which is called after all the
3325 * `iteratee` functions have finished. Result will be either `true` or `false`
3326 * depending on the values of the async tests. Invoked with (err, result).
3327 */
3328var everyLimit = doParallelLimit(_createTester(notId, notId));
3329
3330/**
3331 * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
3332 *
3333 * @name everySeries
3334 * @static
3335 * @memberOf module:Collections
3336 * @method
3337 * @see [async.every]{@link module:Collections.every}
3338 * @alias allSeries
3339 * @category Collection
3340 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3341 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3342 * in the collection in series.
3343 * The iteratee must complete with a boolean result value.
3344 * Invoked with (item, callback).
3345 * @param {Function} [callback] - A callback which is called after all the
3346 * `iteratee` functions have finished. Result will be either `true` or `false`
3347 * depending on the values of the async tests. Invoked with (err, result).
3348 */
3349var everySeries = doLimit(everyLimit, 1);
3350
3351/**
3352 * The base implementation of `_.property` without support for deep paths.
3353 *
3354 * @private
3355 * @param {string} key The key of the property to get.
3356 * @returns {Function} Returns the new accessor function.
3357 */
3358function baseProperty(key) {
3359 return function(object) {
3360 return object == null ? undefined : object[key];
3361 };
3362}
3363
3364function filterArray(eachfn, arr, iteratee, callback) {
3365 var truthValues = new Array(arr.length);
3366 eachfn(arr, function (x, index, callback) {
3367 iteratee(x, function (err, v) {
3368 truthValues[index] = !!v;
3369 callback(err);
3370 });
3371 }, function (err) {
3372 if (err) return callback(err);
3373 var results = [];
3374 for (var i = 0; i < arr.length; i++) {
3375 if (truthValues[i]) results.push(arr[i]);
3376 }
3377 callback(null, results);
3378 });
3379}
3380
3381function filterGeneric(eachfn, coll, iteratee, callback) {
3382 var results = [];
3383 eachfn(coll, function (x, index, callback) {
3384 iteratee(x, function (err, v) {
3385 if (err) {
3386 callback(err);
3387 } else {
3388 if (v) {
3389 results.push({index: index, value: x});
3390 }
3391 callback();
3392 }
3393 });
3394 }, function (err) {
3395 if (err) {
3396 callback(err);
3397 } else {
3398 callback(null, arrayMap(results.sort(function (a, b) {
3399 return a.index - b.index;
3400 }), baseProperty('value')));
3401 }
3402 });
3403}
3404
3405function _filter(eachfn, coll, iteratee, callback) {
3406 var filter = isArrayLike(coll) ? filterArray : filterGeneric;
3407 filter(eachfn, coll, wrapAsync(iteratee), callback || noop);
3408}
3409
3410/**
3411 * Returns a new array of all the values in `coll` which pass an async truth
3412 * test. This operation is performed in parallel, but the results array will be
3413 * in the same order as the original.
3414 *
3415 * @name filter
3416 * @static
3417 * @memberOf module:Collections
3418 * @method
3419 * @alias select
3420 * @category Collection
3421 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3422 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
3423 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
3424 * with a boolean argument once it has completed. Invoked with (item, callback).
3425 * @param {Function} [callback] - A callback which is called after all the
3426 * `iteratee` functions have finished. Invoked with (err, results).
3427 * @example
3428 *
3429 * async.filter(['file1','file2','file3'], function(filePath, callback) {
3430 * fs.access(filePath, function(err) {
3431 * callback(null, !err)
3432 * });
3433 * }, function(err, results) {
3434 * // results now equals an array of the existing files
3435 * });
3436 */
3437var filter = doParallel(_filter);
3438
3439/**
3440 * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
3441 * time.
3442 *
3443 * @name filterLimit
3444 * @static
3445 * @memberOf module:Collections
3446 * @method
3447 * @see [async.filter]{@link module:Collections.filter}
3448 * @alias selectLimit
3449 * @category Collection
3450 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3451 * @param {number} limit - The maximum number of async operations at a time.
3452 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
3453 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
3454 * with a boolean argument once it has completed. Invoked with (item, callback).
3455 * @param {Function} [callback] - A callback which is called after all the
3456 * `iteratee` functions have finished. Invoked with (err, results).
3457 */
3458var filterLimit = doParallelLimit(_filter);
3459
3460/**
3461 * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
3462 *
3463 * @name filterSeries
3464 * @static
3465 * @memberOf module:Collections
3466 * @method
3467 * @see [async.filter]{@link module:Collections.filter}
3468 * @alias selectSeries
3469 * @category Collection
3470 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3471 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
3472 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
3473 * with a boolean argument once it has completed. Invoked with (item, callback).
3474 * @param {Function} [callback] - A callback which is called after all the
3475 * `iteratee` functions have finished. Invoked with (err, results)
3476 */
3477var filterSeries = doLimit(filterLimit, 1);
3478
3479/**
3480 * Calls the asynchronous function `fn` with a callback parameter that allows it
3481 * to call itself again, in series, indefinitely.
3482
3483 * If an error is passed to the callback then `errback` is called with the
3484 * error, and execution stops, otherwise it will never be called.
3485 *
3486 * @name forever
3487 * @static
3488 * @memberOf module:ControlFlow
3489 * @method
3490 * @category Control Flow
3491 * @param {AsyncFunction} fn - an async function to call repeatedly.
3492 * Invoked with (next).
3493 * @param {Function} [errback] - when `fn` passes an error to it's callback,
3494 * this function will be called, and execution stops. Invoked with (err).
3495 * @example
3496 *
3497 * async.forever(
3498 * function(next) {
3499 * // next is suitable for passing to things that need a callback(err [, whatever]);
3500 * // it will result in this function being called again.
3501 * },
3502 * function(err) {
3503 * // if next is called with a value in its first parameter, it will appear
3504 * // in here as 'err', and execution will stop.
3505 * }
3506 * );
3507 */
3508function forever(fn, errback) {
3509 var done = onlyOnce(errback || noop);
3510 var task = wrapAsync(ensureAsync(fn));
3511
3512 function next(err) {
3513 if (err) return done(err);
3514 task(next);
3515 }
3516 next();
3517}
3518
3519/**
3520 * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
3521 *
3522 * @name groupByLimit
3523 * @static
3524 * @memberOf module:Collections
3525 * @method
3526 * @see [async.groupBy]{@link module:Collections.groupBy}
3527 * @category Collection
3528 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3529 * @param {number} limit - The maximum number of async operations at a time.
3530 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3531 * `coll`.
3532 * The iteratee should complete with a `key` to group the value under.
3533 * Invoked with (value, callback).
3534 * @param {Function} [callback] - A callback which is called when all `iteratee`
3535 * functions have finished, or an error occurs. Result is an `Object` whoses
3536 * properties are arrays of values which returned the corresponding key.
3537 */
3538var groupByLimit = function(coll, limit, iteratee, callback) {
3539 callback = callback || noop;
3540 var _iteratee = wrapAsync(iteratee);
3541 mapLimit(coll, limit, function(val, callback) {
3542 _iteratee(val, function(err, key) {
3543 if (err) return callback(err);
3544 return callback(null, {key: key, val: val});
3545 });
3546 }, function(err, mapResults) {
3547 var result = {};
3548 // from MDN, handle object having an `hasOwnProperty` prop
3549 var hasOwnProperty = Object.prototype.hasOwnProperty;
3550
3551 for (var i = 0; i < mapResults.length; i++) {
3552 if (mapResults[i]) {
3553 var key = mapResults[i].key;
3554 var val = mapResults[i].val;
3555
3556 if (hasOwnProperty.call(result, key)) {
3557 result[key].push(val);
3558 } else {
3559 result[key] = [val];
3560 }
3561 }
3562 }
3563
3564 return callback(err, result);
3565 });
3566};
3567
3568/**
3569 * Returns a new object, where each value corresponds to an array of items, from
3570 * `coll`, that returned the corresponding key. That is, the keys of the object
3571 * correspond to the values passed to the `iteratee` callback.
3572 *
3573 * Note: Since this function applies the `iteratee` to each item in parallel,
3574 * there is no guarantee that the `iteratee` functions will complete in order.
3575 * However, the values for each key in the `result` will be in the same order as
3576 * the original `coll`. For Objects, the values will roughly be in the order of
3577 * the original Objects' keys (but this can vary across JavaScript engines).
3578 *
3579 * @name groupBy
3580 * @static
3581 * @memberOf module:Collections
3582 * @method
3583 * @category Collection
3584 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3585 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3586 * `coll`.
3587 * The iteratee should complete with a `key` to group the value under.
3588 * Invoked with (value, callback).
3589 * @param {Function} [callback] - A callback which is called when all `iteratee`
3590 * functions have finished, or an error occurs. Result is an `Object` whoses
3591 * properties are arrays of values which returned the corresponding key.
3592 * @example
3593 *
3594 * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) {
3595 * db.findById(userId, function(err, user) {
3596 * if (err) return callback(err);
3597 * return callback(null, user.age);
3598 * });
3599 * }, function(err, result) {
3600 * // result is object containing the userIds grouped by age
3601 * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']};
3602 * });
3603 */
3604var groupBy = doLimit(groupByLimit, Infinity);
3605
3606/**
3607 * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
3608 *
3609 * @name groupBySeries
3610 * @static
3611 * @memberOf module:Collections
3612 * @method
3613 * @see [async.groupBy]{@link module:Collections.groupBy}
3614 * @category Collection
3615 * @param {Array|Iterable|Object} coll - A collection to iterate over.
3616 * @param {number} limit - The maximum number of async operations at a time.
3617 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3618 * `coll`.
3619 * The iteratee should complete with a `key` to group the value under.
3620 * Invoked with (value, callback).
3621 * @param {Function} [callback] - A callback which is called when all `iteratee`
3622 * functions have finished, or an error occurs. Result is an `Object` whoses
3623 * properties are arrays of values which returned the corresponding key.
3624 */
3625var groupBySeries = doLimit(groupByLimit, 1);
3626
3627/**
3628 * Logs the result of an `async` function to the `console`. Only works in
3629 * Node.js or in browsers that support `console.log` and `console.error` (such
3630 * as FF and Chrome). If multiple arguments are returned from the async
3631 * function, `console.log` is called on each argument in order.
3632 *
3633 * @name log
3634 * @static
3635 * @memberOf module:Utils
3636 * @method
3637 * @category Util
3638 * @param {AsyncFunction} function - The function you want to eventually apply
3639 * all arguments to.
3640 * @param {...*} arguments... - Any number of arguments to apply to the function.
3641 * @example
3642 *
3643 * // in a module
3644 * var hello = function(name, callback) {
3645 * setTimeout(function() {
3646 * callback(null, 'hello ' + name);
3647 * }, 1000);
3648 * };
3649 *
3650 * // in the node repl
3651 * node> async.log(hello, 'world');
3652 * 'hello world'
3653 */
3654var log = consoleFunc('log');
3655
3656/**
3657 * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
3658 * time.
3659 *
3660 * @name mapValuesLimit
3661 * @static
3662 * @memberOf module:Collections
3663 * @method
3664 * @see [async.mapValues]{@link module:Collections.mapValues}
3665 * @category Collection
3666 * @param {Object} obj - A collection to iterate over.
3667 * @param {number} limit - The maximum number of async operations at a time.
3668 * @param {AsyncFunction} iteratee - A function to apply to each value and key
3669 * in `coll`.
3670 * The iteratee should complete with the transformed value as its result.
3671 * Invoked with (value, key, callback).
3672 * @param {Function} [callback] - A callback which is called when all `iteratee`
3673 * functions have finished, or an error occurs. `result` is a new object consisting
3674 * of each key from `obj`, with each transformed value on the right-hand side.
3675 * Invoked with (err, result).
3676 */
3677function mapValuesLimit(obj, limit, iteratee, callback) {
3678 callback = once(callback || noop);
3679 var newObj = {};
3680 var _iteratee = wrapAsync(iteratee);
3681 eachOfLimit(obj, limit, function(val, key, next) {
3682 _iteratee(val, key, function (err, result) {
3683 if (err) return next(err);
3684 newObj[key] = result;
3685 next();
3686 });
3687 }, function (err) {
3688 callback(err, newObj);
3689 });
3690}
3691
3692/**
3693 * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.
3694 *
3695 * Produces a new Object by mapping each value of `obj` through the `iteratee`
3696 * function. The `iteratee` is called each `value` and `key` from `obj` and a
3697 * callback for when it has finished processing. Each of these callbacks takes
3698 * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`
3699 * passes an error to its callback, the main `callback` (for the `mapValues`
3700 * function) is immediately called with the error.
3701 *
3702 * Note, the order of the keys in the result is not guaranteed. The keys will
3703 * be roughly in the order they complete, (but this is very engine-specific)
3704 *
3705 * @name mapValues
3706 * @static
3707 * @memberOf module:Collections
3708 * @method
3709 * @category Collection
3710 * @param {Object} obj - A collection to iterate over.
3711 * @param {AsyncFunction} iteratee - A function to apply to each value and key
3712 * in `coll`.
3713 * The iteratee should complete with the transformed value as its result.
3714 * Invoked with (value, key, callback).
3715 * @param {Function} [callback] - A callback which is called when all `iteratee`
3716 * functions have finished, or an error occurs. `result` is a new object consisting
3717 * of each key from `obj`, with each transformed value on the right-hand side.
3718 * Invoked with (err, result).
3719 * @example
3720 *
3721 * async.mapValues({
3722 * f1: 'file1',
3723 * f2: 'file2',
3724 * f3: 'file3'
3725 * }, function (file, key, callback) {
3726 * fs.stat(file, callback);
3727 * }, function(err, result) {
3728 * // result is now a map of stats for each file, e.g.
3729 * // {
3730 * // f1: [stats for file1],
3731 * // f2: [stats for file2],
3732 * // f3: [stats for file3]
3733 * // }
3734 * });
3735 */
3736
3737var mapValues = doLimit(mapValuesLimit, Infinity);
3738
3739/**
3740 * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.
3741 *
3742 * @name mapValuesSeries
3743 * @static
3744 * @memberOf module:Collections
3745 * @method
3746 * @see [async.mapValues]{@link module:Collections.mapValues}
3747 * @category Collection
3748 * @param {Object} obj - A collection to iterate over.
3749 * @param {AsyncFunction} iteratee - A function to apply to each value and key
3750 * in `coll`.
3751 * The iteratee should complete with the transformed value as its result.
3752 * Invoked with (value, key, callback).
3753 * @param {Function} [callback] - A callback which is called when all `iteratee`
3754 * functions have finished, or an error occurs. `result` is a new object consisting
3755 * of each key from `obj`, with each transformed value on the right-hand side.
3756 * Invoked with (err, result).
3757 */
3758var mapValuesSeries = doLimit(mapValuesLimit, 1);
3759
3760function has(obj, key) {
3761 return key in obj;
3762}
3763
3764/**
3765 * Caches the results of an async function. When creating a hash to store
3766 * function results against, the callback is omitted from the hash and an
3767 * optional hash function can be used.
3768 *
3769 * If no hash function is specified, the first argument is used as a hash key,
3770 * which may work reasonably if it is a string or a data type that converts to a
3771 * distinct string. Note that objects and arrays will not behave reasonably.
3772 * Neither will cases where the other arguments are significant. In such cases,
3773 * specify your own hash function.
3774 *
3775 * The cache of results is exposed as the `memo` property of the function
3776 * returned by `memoize`.
3777 *
3778 * @name memoize
3779 * @static
3780 * @memberOf module:Utils
3781 * @method
3782 * @category Util
3783 * @param {AsyncFunction} fn - The async function to proxy and cache results from.
3784 * @param {Function} hasher - An optional function for generating a custom hash
3785 * for storing results. It has all the arguments applied to it apart from the
3786 * callback, and must be synchronous.
3787 * @returns {AsyncFunction} a memoized version of `fn`
3788 * @example
3789 *
3790 * var slow_fn = function(name, callback) {
3791 * // do something
3792 * callback(null, result);
3793 * };
3794 * var fn = async.memoize(slow_fn);
3795 *
3796 * // fn can now be used as if it were slow_fn
3797 * fn('some name', function() {
3798 * // callback
3799 * });
3800 */
3801function memoize(fn, hasher) {
3802 var memo = Object.create(null);
3803 var queues = Object.create(null);
3804 hasher = hasher || identity;
3805 var _fn = wrapAsync(fn);
3806 var memoized = initialParams(function memoized(args, callback) {
3807 var key = hasher.apply(null, args);
3808 if (has(memo, key)) {
3809 setImmediate$1(function() {
3810 callback.apply(null, memo[key]);
3811 });
3812 } else if (has(queues, key)) {
3813 queues[key].push(callback);
3814 } else {
3815 queues[key] = [callback];
3816 _fn.apply(null, args.concat(function(/*args*/) {
3817 var args = slice(arguments);
3818 memo[key] = args;
3819 var q = queues[key];
3820 delete queues[key];
3821 for (var i = 0, l = q.length; i < l; i++) {
3822 q[i].apply(null, args);
3823 }
3824 }));
3825 }
3826 });
3827 memoized.memo = memo;
3828 memoized.unmemoized = fn;
3829 return memoized;
3830}
3831
3832/**
3833 * Calls `callback` on a later loop around the event loop. In Node.js this just
3834 * calls `process.nextTick`. In the browser it will use `setImmediate` if
3835 * available, otherwise `setTimeout(callback, 0)`, which means other higher
3836 * priority events may precede the execution of `callback`.
3837 *
3838 * This is used internally for browser-compatibility purposes.
3839 *
3840 * @name nextTick
3841 * @static
3842 * @memberOf module:Utils
3843 * @method
3844 * @see [async.setImmediate]{@link module:Utils.setImmediate}
3845 * @category Util
3846 * @param {Function} callback - The function to call on a later loop around
3847 * the event loop. Invoked with (args...).
3848 * @param {...*} args... - any number of additional arguments to pass to the
3849 * callback on the next tick.
3850 * @example
3851 *
3852 * var call_order = [];
3853 * async.nextTick(function() {
3854 * call_order.push('two');
3855 * // call_order now equals ['one','two']
3856 * });
3857 * call_order.push('one');
3858 *
3859 * async.setImmediate(function (a, b, c) {
3860 * // a, b, and c equal 1, 2, and 3
3861 * }, 1, 2, 3);
3862 */
3863var _defer$1;
3864
3865if (hasNextTick) {
3866 _defer$1 = process.nextTick;
3867} else if (hasSetImmediate) {
3868 _defer$1 = setImmediate;
3869} else {
3870 _defer$1 = fallback;
3871}
3872
3873var nextTick = wrap(_defer$1);
3874
3875function _parallel(eachfn, tasks, callback) {
3876 callback = callback || noop;
3877 var results = isArrayLike(tasks) ? [] : {};
3878
3879 eachfn(tasks, function (task, key, callback) {
3880 wrapAsync(task)(function (err, result) {
3881 if (arguments.length > 2) {
3882 result = slice(arguments, 1);
3883 }
3884 results[key] = result;
3885 callback(err);
3886 });
3887 }, function (err) {
3888 callback(err, results);
3889 });
3890}
3891
3892/**
3893 * Run the `tasks` collection of functions in parallel, without waiting until
3894 * the previous function has completed. If any of the functions pass an error to
3895 * its callback, the main `callback` is immediately called with the value of the
3896 * error. Once the `tasks` have completed, the results are passed to the final
3897 * `callback` as an array.
3898 *
3899 * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about
3900 * parallel execution of code. If your tasks do not use any timers or perform
3901 * any I/O, they will actually be executed in series. Any synchronous setup
3902 * sections for each task will happen one after the other. JavaScript remains
3903 * single-threaded.
3904 *
3905 * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
3906 * execution of other tasks when a task fails.
3907 *
3908 * It is also possible to use an object instead of an array. Each property will
3909 * be run as a function and the results will be passed to the final `callback`
3910 * as an object instead of an array. This can be a more readable way of handling
3911 * results from {@link async.parallel}.
3912 *
3913 * @name parallel
3914 * @static
3915 * @memberOf module:ControlFlow
3916 * @method
3917 * @category Control Flow
3918 * @param {Array|Iterable|Object} tasks - A collection of
3919 * [async functions]{@link AsyncFunction} to run.
3920 * Each async function can complete with any number of optional `result` values.
3921 * @param {Function} [callback] - An optional callback to run once all the
3922 * functions have completed successfully. This function gets a results array
3923 * (or object) containing all the result arguments passed to the task callbacks.
3924 * Invoked with (err, results).
3925 *
3926 * @example
3927 * async.parallel([
3928 * function(callback) {
3929 * setTimeout(function() {
3930 * callback(null, 'one');
3931 * }, 200);
3932 * },
3933 * function(callback) {
3934 * setTimeout(function() {
3935 * callback(null, 'two');
3936 * }, 100);
3937 * }
3938 * ],
3939 * // optional callback
3940 * function(err, results) {
3941 * // the results array will equal ['one','two'] even though
3942 * // the second function had a shorter timeout.
3943 * });
3944 *
3945 * // an example using an object instead of an array
3946 * async.parallel({
3947 * one: function(callback) {
3948 * setTimeout(function() {
3949 * callback(null, 1);
3950 * }, 200);
3951 * },
3952 * two: function(callback) {
3953 * setTimeout(function() {
3954 * callback(null, 2);
3955 * }, 100);
3956 * }
3957 * }, function(err, results) {
3958 * // results is now equals to: {one: 1, two: 2}
3959 * });
3960 */
3961function parallelLimit(tasks, callback) {
3962 _parallel(eachOf, tasks, callback);
3963}
3964
3965/**
3966 * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a
3967 * time.
3968 *
3969 * @name parallelLimit
3970 * @static
3971 * @memberOf module:ControlFlow
3972 * @method
3973 * @see [async.parallel]{@link module:ControlFlow.parallel}
3974 * @category Control Flow
3975 * @param {Array|Iterable|Object} tasks - A collection of
3976 * [async functions]{@link AsyncFunction} to run.
3977 * Each async function can complete with any number of optional `result` values.
3978 * @param {number} limit - The maximum number of async operations at a time.
3979 * @param {Function} [callback] - An optional callback to run once all the
3980 * functions have completed successfully. This function gets a results array
3981 * (or object) containing all the result arguments passed to the task callbacks.
3982 * Invoked with (err, results).
3983 */
3984function parallelLimit$1(tasks, limit, callback) {
3985 _parallel(_eachOfLimit(limit), tasks, callback);
3986}
3987
3988/**
3989 * A queue of tasks for the worker function to complete.
3990 * @typedef {Object} QueueObject
3991 * @memberOf module:ControlFlow
3992 * @property {Function} length - a function returning the number of items
3993 * waiting to be processed. Invoke with `queue.length()`.
3994 * @property {boolean} started - a boolean indicating whether or not any
3995 * items have been pushed and processed by the queue.
3996 * @property {Function} running - a function returning the number of items
3997 * currently being processed. Invoke with `queue.running()`.
3998 * @property {Function} workersList - a function returning the array of items
3999 * currently being processed. Invoke with `queue.workersList()`.
4000 * @property {Function} idle - a function returning false if there are items
4001 * waiting or being processed, or true if not. Invoke with `queue.idle()`.
4002 * @property {number} concurrency - an integer for determining how many `worker`
4003 * functions should be run in parallel. This property can be changed after a
4004 * `queue` is created to alter the concurrency on-the-fly.
4005 * @property {Function} push - add a new task to the `queue`. Calls `callback`
4006 * once the `worker` has finished processing the task. Instead of a single task,
4007 * a `tasks` array can be submitted. The respective callback is used for every
4008 * task in the list. Invoke with `queue.push(task, [callback])`,
4009 * @property {Function} unshift - add a new task to the front of the `queue`.
4010 * Invoke with `queue.unshift(task, [callback])`.
4011 * @property {Function} remove - remove items from the queue that match a test
4012 * function. The test function will be passed an object with a `data` property,
4013 * and a `priority` property, if this is a
4014 * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
4015 * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
4016 * `function ({data, priority}) {}` and returns a Boolean.
4017 * @property {Function} saturated - a callback that is called when the number of
4018 * running workers hits the `concurrency` limit, and further tasks will be
4019 * queued.
4020 * @property {Function} unsaturated - a callback that is called when the number
4021 * of running workers is less than the `concurrency` & `buffer` limits, and
4022 * further tasks will not be queued.
4023 * @property {number} buffer - A minimum threshold buffer in order to say that
4024 * the `queue` is `unsaturated`.
4025 * @property {Function} empty - a callback that is called when the last item
4026 * from the `queue` is given to a `worker`.
4027 * @property {Function} drain - a callback that is called when the last item
4028 * from the `queue` has returned from the `worker`.
4029 * @property {Function} error - a callback that is called when a task errors.
4030 * Has the signature `function(error, task)`.
4031 * @property {boolean} paused - a boolean for determining whether the queue is
4032 * in a paused state.
4033 * @property {Function} pause - a function that pauses the processing of tasks
4034 * until `resume()` is called. Invoke with `queue.pause()`.
4035 * @property {Function} resume - a function that resumes the processing of
4036 * queued tasks when the queue is paused. Invoke with `queue.resume()`.
4037 * @property {Function} kill - a function that removes the `drain` callback and
4038 * empties remaining tasks from the queue forcing it to go idle. No more tasks
4039 * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.
4040 */
4041
4042/**
4043 * Creates a `queue` object with the specified `concurrency`. Tasks added to the
4044 * `queue` are processed in parallel (up to the `concurrency` limit). If all
4045 * `worker`s are in progress, the task is queued until one becomes available.
4046 * Once a `worker` completes a `task`, that `task`'s callback is called.
4047 *
4048 * @name queue
4049 * @static
4050 * @memberOf module:ControlFlow
4051 * @method
4052 * @category Control Flow
4053 * @param {AsyncFunction} worker - An async function for processing a queued task.
4054 * If you want to handle errors from an individual task, pass a callback to
4055 * `q.push()`. Invoked with (task, callback).
4056 * @param {number} [concurrency=1] - An `integer` for determining how many
4057 * `worker` functions should be run in parallel. If omitted, the concurrency
4058 * defaults to `1`. If the concurrency is `0`, an error is thrown.
4059 * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can
4060 * attached as certain properties to listen for specific events during the
4061 * lifecycle of the queue.
4062 * @example
4063 *
4064 * // create a queue object with concurrency 2
4065 * var q = async.queue(function(task, callback) {
4066 * console.log('hello ' + task.name);
4067 * callback();
4068 * }, 2);
4069 *
4070 * // assign a callback
4071 * q.drain = function() {
4072 * console.log('all items have been processed');
4073 * };
4074 *
4075 * // add some items to the queue
4076 * q.push({name: 'foo'}, function(err) {
4077 * console.log('finished processing foo');
4078 * });
4079 * q.push({name: 'bar'}, function (err) {
4080 * console.log('finished processing bar');
4081 * });
4082 *
4083 * // add some items to the queue (batch-wise)
4084 * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
4085 * console.log('finished processing item');
4086 * });
4087 *
4088 * // add some items to the front of the queue
4089 * q.unshift({name: 'bar'}, function (err) {
4090 * console.log('finished processing bar');
4091 * });
4092 */
4093var queue$1 = function (worker, concurrency) {
4094 var _worker = wrapAsync(worker);
4095 return queue(function (items, cb) {
4096 _worker(items[0], cb);
4097 }, concurrency, 1);
4098};
4099
4100/**
4101 * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and
4102 * completed in ascending priority order.
4103 *
4104 * @name priorityQueue
4105 * @static
4106 * @memberOf module:ControlFlow
4107 * @method
4108 * @see [async.queue]{@link module:ControlFlow.queue}
4109 * @category Control Flow
4110 * @param {AsyncFunction} worker - An async function for processing a queued task.
4111 * If you want to handle errors from an individual task, pass a callback to
4112 * `q.push()`.
4113 * Invoked with (task, callback).
4114 * @param {number} concurrency - An `integer` for determining how many `worker`
4115 * functions should be run in parallel. If omitted, the concurrency defaults to
4116 * `1`. If the concurrency is `0`, an error is thrown.
4117 * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two
4118 * differences between `queue` and `priorityQueue` objects:
4119 * * `push(task, priority, [callback])` - `priority` should be a number. If an
4120 * array of `tasks` is given, all tasks will be assigned the same priority.
4121 * * The `unshift` method was removed.
4122 */
4123var priorityQueue = function(worker, concurrency) {
4124 // Start with a normal queue
4125 var q = queue$1(worker, concurrency);
4126
4127 // Override push to accept second parameter representing priority
4128 q.push = function(data, priority, callback) {
4129 if (callback == null) callback = noop;
4130 if (typeof callback !== 'function') {
4131 throw new Error('task callback must be a function');
4132 }
4133 q.started = true;
4134 if (!isArray(data)) {
4135 data = [data];
4136 }
4137 if (data.length === 0) {
4138 // call drain immediately if there are no tasks
4139 return setImmediate$1(function() {
4140 q.drain();
4141 });
4142 }
4143
4144 priority = priority || 0;
4145 var nextNode = q._tasks.head;
4146 while (nextNode && priority >= nextNode.priority) {
4147 nextNode = nextNode.next;
4148 }
4149
4150 for (var i = 0, l = data.length; i < l; i++) {
4151 var item = {
4152 data: data[i],
4153 priority: priority,
4154 callback: callback
4155 };
4156
4157 if (nextNode) {
4158 q._tasks.insertBefore(nextNode, item);
4159 } else {
4160 q._tasks.push(item);
4161 }
4162 }
4163 setImmediate$1(q.process);
4164 };
4165
4166 // Remove unshift function
4167 delete q.unshift;
4168
4169 return q;
4170};
4171
4172/**
4173 * Runs the `tasks` array of functions in parallel, without waiting until the
4174 * previous function has completed. Once any of the `tasks` complete or pass an
4175 * error to its callback, the main `callback` is immediately called. It's
4176 * equivalent to `Promise.race()`.
4177 *
4178 * @name race
4179 * @static
4180 * @memberOf module:ControlFlow
4181 * @method
4182 * @category Control Flow
4183 * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
4184 * to run. Each function can complete with an optional `result` value.
4185 * @param {Function} callback - A callback to run once any of the functions have
4186 * completed. This function gets an error or result from the first function that
4187 * completed. Invoked with (err, result).
4188 * @returns undefined
4189 * @example
4190 *
4191 * async.race([
4192 * function(callback) {
4193 * setTimeout(function() {
4194 * callback(null, 'one');
4195 * }, 200);
4196 * },
4197 * function(callback) {
4198 * setTimeout(function() {
4199 * callback(null, 'two');
4200 * }, 100);
4201 * }
4202 * ],
4203 * // main callback
4204 * function(err, result) {
4205 * // the result will be equal to 'two' as it finishes earlier
4206 * });
4207 */
4208function race(tasks, callback) {
4209 callback = once(callback || noop);
4210 if (!isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
4211 if (!tasks.length) return callback();
4212 for (var i = 0, l = tasks.length; i < l; i++) {
4213 wrapAsync(tasks[i])(callback);
4214 }
4215}
4216
4217/**
4218 * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
4219 *
4220 * @name reduceRight
4221 * @static
4222 * @memberOf module:Collections
4223 * @method
4224 * @see [async.reduce]{@link module:Collections.reduce}
4225 * @alias foldr
4226 * @category Collection
4227 * @param {Array} array - A collection to iterate over.
4228 * @param {*} memo - The initial state of the reduction.
4229 * @param {AsyncFunction} iteratee - A function applied to each item in the
4230 * array to produce the next step in the reduction.
4231 * The `iteratee` should complete with the next state of the reduction.
4232 * If the iteratee complete with an error, the reduction is stopped and the
4233 * main `callback` is immediately called with the error.
4234 * Invoked with (memo, item, callback).
4235 * @param {Function} [callback] - A callback which is called after all the
4236 * `iteratee` functions have finished. Result is the reduced value. Invoked with
4237 * (err, result).
4238 */
4239function reduceRight (array, memo, iteratee, callback) {
4240 var reversed = slice(array).reverse();
4241 reduce(reversed, memo, iteratee, callback);
4242}
4243
4244/**
4245 * Wraps the async function in another function that always completes with a
4246 * result object, even when it errors.
4247 *
4248 * The result object has either the property `error` or `value`.
4249 *
4250 * @name reflect
4251 * @static
4252 * @memberOf module:Utils
4253 * @method
4254 * @category Util
4255 * @param {AsyncFunction} fn - The async function you want to wrap
4256 * @returns {Function} - A function that always passes null to it's callback as
4257 * the error. The second argument to the callback will be an `object` with
4258 * either an `error` or a `value` property.
4259 * @example
4260 *
4261 * async.parallel([
4262 * async.reflect(function(callback) {
4263 * // do some stuff ...
4264 * callback(null, 'one');
4265 * }),
4266 * async.reflect(function(callback) {
4267 * // do some more stuff but error ...
4268 * callback('bad stuff happened');
4269 * }),
4270 * async.reflect(function(callback) {
4271 * // do some more stuff ...
4272 * callback(null, 'two');
4273 * })
4274 * ],
4275 * // optional callback
4276 * function(err, results) {
4277 * // values
4278 * // results[0].value = 'one'
4279 * // results[1].error = 'bad stuff happened'
4280 * // results[2].value = 'two'
4281 * });
4282 */
4283function reflect(fn) {
4284 var _fn = wrapAsync(fn);
4285 return initialParams(function reflectOn(args, reflectCallback) {
4286 args.push(function callback(error, cbArg) {
4287 if (error) {
4288 reflectCallback(null, { error: error });
4289 } else {
4290 var value;
4291 if (arguments.length <= 2) {
4292 value = cbArg;
4293 } else {
4294 value = slice(arguments, 1);
4295 }
4296 reflectCallback(null, { value: value });
4297 }
4298 });
4299
4300 return _fn.apply(this, args);
4301 });
4302}
4303
4304/**
4305 * A helper function that wraps an array or an object of functions with `reflect`.
4306 *
4307 * @name reflectAll
4308 * @static
4309 * @memberOf module:Utils
4310 * @method
4311 * @see [async.reflect]{@link module:Utils.reflect}
4312 * @category Util
4313 * @param {Array|Object|Iterable} tasks - The collection of
4314 * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
4315 * @returns {Array} Returns an array of async functions, each wrapped in
4316 * `async.reflect`
4317 * @example
4318 *
4319 * let tasks = [
4320 * function(callback) {
4321 * setTimeout(function() {
4322 * callback(null, 'one');
4323 * }, 200);
4324 * },
4325 * function(callback) {
4326 * // do some more stuff but error ...
4327 * callback(new Error('bad stuff happened'));
4328 * },
4329 * function(callback) {
4330 * setTimeout(function() {
4331 * callback(null, 'two');
4332 * }, 100);
4333 * }
4334 * ];
4335 *
4336 * async.parallel(async.reflectAll(tasks),
4337 * // optional callback
4338 * function(err, results) {
4339 * // values
4340 * // results[0].value = 'one'
4341 * // results[1].error = Error('bad stuff happened')
4342 * // results[2].value = 'two'
4343 * });
4344 *
4345 * // an example using an object instead of an array
4346 * let tasks = {
4347 * one: function(callback) {
4348 * setTimeout(function() {
4349 * callback(null, 'one');
4350 * }, 200);
4351 * },
4352 * two: function(callback) {
4353 * callback('two');
4354 * },
4355 * three: function(callback) {
4356 * setTimeout(function() {
4357 * callback(null, 'three');
4358 * }, 100);
4359 * }
4360 * };
4361 *
4362 * async.parallel(async.reflectAll(tasks),
4363 * // optional callback
4364 * function(err, results) {
4365 * // values
4366 * // results.one.value = 'one'
4367 * // results.two.error = 'two'
4368 * // results.three.value = 'three'
4369 * });
4370 */
4371function reflectAll(tasks) {
4372 var results;
4373 if (isArray(tasks)) {
4374 results = arrayMap(tasks, reflect);
4375 } else {
4376 results = {};
4377 baseForOwn(tasks, function(task, key) {
4378 results[key] = reflect.call(this, task);
4379 });
4380 }
4381 return results;
4382}
4383
4384function reject$1(eachfn, arr, iteratee, callback) {
4385 _filter(eachfn, arr, function(value, cb) {
4386 iteratee(value, function(err, v) {
4387 cb(err, !v);
4388 });
4389 }, callback);
4390}
4391
4392/**
4393 * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
4394 *
4395 * @name reject
4396 * @static
4397 * @memberOf module:Collections
4398 * @method
4399 * @see [async.filter]{@link module:Collections.filter}
4400 * @category Collection
4401 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4402 * @param {Function} iteratee - An async truth test to apply to each item in
4403 * `coll`.
4404 * The should complete with a boolean value as its `result`.
4405 * Invoked with (item, callback).
4406 * @param {Function} [callback] - A callback which is called after all the
4407 * `iteratee` functions have finished. Invoked with (err, results).
4408 * @example
4409 *
4410 * async.reject(['file1','file2','file3'], function(filePath, callback) {
4411 * fs.access(filePath, function(err) {
4412 * callback(null, !err)
4413 * });
4414 * }, function(err, results) {
4415 * // results now equals an array of missing files
4416 * createFiles(results);
4417 * });
4418 */
4419var reject = doParallel(reject$1);
4420
4421/**
4422 * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
4423 * time.
4424 *
4425 * @name rejectLimit
4426 * @static
4427 * @memberOf module:Collections
4428 * @method
4429 * @see [async.reject]{@link module:Collections.reject}
4430 * @category Collection
4431 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4432 * @param {number} limit - The maximum number of async operations at a time.
4433 * @param {Function} iteratee - An async truth test to apply to each item in
4434 * `coll`.
4435 * The should complete with a boolean value as its `result`.
4436 * Invoked with (item, callback).
4437 * @param {Function} [callback] - A callback which is called after all the
4438 * `iteratee` functions have finished. Invoked with (err, results).
4439 */
4440var rejectLimit = doParallelLimit(reject$1);
4441
4442/**
4443 * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
4444 *
4445 * @name rejectSeries
4446 * @static
4447 * @memberOf module:Collections
4448 * @method
4449 * @see [async.reject]{@link module:Collections.reject}
4450 * @category Collection
4451 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4452 * @param {Function} iteratee - An async truth test to apply to each item in
4453 * `coll`.
4454 * The should complete with a boolean value as its `result`.
4455 * Invoked with (item, callback).
4456 * @param {Function} [callback] - A callback which is called after all the
4457 * `iteratee` functions have finished. Invoked with (err, results).
4458 */
4459var rejectSeries = doLimit(rejectLimit, 1);
4460
4461/**
4462 * Creates a function that returns `value`.
4463 *
4464 * @static
4465 * @memberOf _
4466 * @since 2.4.0
4467 * @category Util
4468 * @param {*} value The value to return from the new function.
4469 * @returns {Function} Returns the new constant function.
4470 * @example
4471 *
4472 * var objects = _.times(2, _.constant({ 'a': 1 }));
4473 *
4474 * console.log(objects);
4475 * // => [{ 'a': 1 }, { 'a': 1 }]
4476 *
4477 * console.log(objects[0] === objects[1]);
4478 * // => true
4479 */
4480function constant$1(value) {
4481 return function() {
4482 return value;
4483 };
4484}
4485
4486/**
4487 * Attempts to get a successful response from `task` no more than `times` times
4488 * before returning an error. If the task is successful, the `callback` will be
4489 * passed the result of the successful task. If all attempts fail, the callback
4490 * will be passed the error and result (if any) of the final attempt.
4491 *
4492 * @name retry
4493 * @static
4494 * @memberOf module:ControlFlow
4495 * @method
4496 * @category Control Flow
4497 * @see [async.retryable]{@link module:ControlFlow.retryable}
4498 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
4499 * object with `times` and `interval` or a number.
4500 * * `times` - The number of attempts to make before giving up. The default
4501 * is `5`.
4502 * * `interval` - The time to wait between retries, in milliseconds. The
4503 * default is `0`. The interval may also be specified as a function of the
4504 * retry count (see example).
4505 * * `errorFilter` - An optional synchronous function that is invoked on
4506 * erroneous result. If it returns `true` the retry attempts will continue;
4507 * if the function returns `false` the retry flow is aborted with the current
4508 * attempt's error and result being returned to the final callback.
4509 * Invoked with (err).
4510 * * If `opts` is a number, the number specifies the number of times to retry,
4511 * with the default interval of `0`.
4512 * @param {AsyncFunction} task - An async function to retry.
4513 * Invoked with (callback).
4514 * @param {Function} [callback] - An optional callback which is called when the
4515 * task has succeeded, or after the final failed attempt. It receives the `err`
4516 * and `result` arguments of the last attempt at completing the `task`. Invoked
4517 * with (err, results).
4518 *
4519 * @example
4520 *
4521 * // The `retry` function can be used as a stand-alone control flow by passing
4522 * // a callback, as shown below:
4523 *
4524 * // try calling apiMethod 3 times
4525 * async.retry(3, apiMethod, function(err, result) {
4526 * // do something with the result
4527 * });
4528 *
4529 * // try calling apiMethod 3 times, waiting 200 ms between each retry
4530 * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
4531 * // do something with the result
4532 * });
4533 *
4534 * // try calling apiMethod 10 times with exponential backoff
4535 * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
4536 * async.retry({
4537 * times: 10,
4538 * interval: function(retryCount) {
4539 * return 50 * Math.pow(2, retryCount);
4540 * }
4541 * }, apiMethod, function(err, result) {
4542 * // do something with the result
4543 * });
4544 *
4545 * // try calling apiMethod the default 5 times no delay between each retry
4546 * async.retry(apiMethod, function(err, result) {
4547 * // do something with the result
4548 * });
4549 *
4550 * // try calling apiMethod only when error condition satisfies, all other
4551 * // errors will abort the retry control flow and return to final callback
4552 * async.retry({
4553 * errorFilter: function(err) {
4554 * return err.message === 'Temporary error'; // only retry on a specific error
4555 * }
4556 * }, apiMethod, function(err, result) {
4557 * // do something with the result
4558 * });
4559 *
4560 * // to retry individual methods that are not as reliable within other
4561 * // control flow functions, use the `retryable` wrapper:
4562 * async.auto({
4563 * users: api.getUsers.bind(api),
4564 * payments: async.retryable(3, api.getPayments.bind(api))
4565 * }, function(err, results) {
4566 * // do something with the results
4567 * });
4568 *
4569 */
4570function retry(opts, task, callback) {
4571 var DEFAULT_TIMES = 5;
4572 var DEFAULT_INTERVAL = 0;
4573
4574 var options = {
4575 times: DEFAULT_TIMES,
4576 intervalFunc: constant$1(DEFAULT_INTERVAL)
4577 };
4578
4579 function parseTimes(acc, t) {
4580 if (typeof t === 'object') {
4581 acc.times = +t.times || DEFAULT_TIMES;
4582
4583 acc.intervalFunc = typeof t.interval === 'function' ?
4584 t.interval :
4585 constant$1(+t.interval || DEFAULT_INTERVAL);
4586
4587 acc.errorFilter = t.errorFilter;
4588 } else if (typeof t === 'number' || typeof t === 'string') {
4589 acc.times = +t || DEFAULT_TIMES;
4590 } else {
4591 throw new Error("Invalid arguments for async.retry");
4592 }
4593 }
4594
4595 if (arguments.length < 3 && typeof opts === 'function') {
4596 callback = task || noop;
4597 task = opts;
4598 } else {
4599 parseTimes(options, opts);
4600 callback = callback || noop;
4601 }
4602
4603 if (typeof task !== 'function') {
4604 throw new Error("Invalid arguments for async.retry");
4605 }
4606
4607 var _task = wrapAsync(task);
4608
4609 var attempt = 1;
4610 function retryAttempt() {
4611 _task(function(err) {
4612 if (err && attempt++ < options.times &&
4613 (typeof options.errorFilter != 'function' ||
4614 options.errorFilter(err))) {
4615 setTimeout(retryAttempt, options.intervalFunc(attempt));
4616 } else {
4617 callback.apply(null, arguments);
4618 }
4619 });
4620 }
4621
4622 retryAttempt();
4623}
4624
4625/**
4626 * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method
4627 * wraps a task and makes it retryable, rather than immediately calling it
4628 * with retries.
4629 *
4630 * @name retryable
4631 * @static
4632 * @memberOf module:ControlFlow
4633 * @method
4634 * @see [async.retry]{@link module:ControlFlow.retry}
4635 * @category Control Flow
4636 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
4637 * options, exactly the same as from `retry`
4638 * @param {AsyncFunction} task - the asynchronous function to wrap.
4639 * This function will be passed any arguments passed to the returned wrapper.
4640 * Invoked with (...args, callback).
4641 * @returns {AsyncFunction} The wrapped function, which when invoked, will
4642 * retry on an error, based on the parameters specified in `opts`.
4643 * This function will accept the same parameters as `task`.
4644 * @example
4645 *
4646 * async.auto({
4647 * dep1: async.retryable(3, getFromFlakyService),
4648 * process: ["dep1", async.retryable(3, function (results, cb) {
4649 * maybeProcessData(results.dep1, cb);
4650 * })]
4651 * }, callback);
4652 */
4653var retryable = function (opts, task) {
4654 if (!task) {
4655 task = opts;
4656 opts = null;
4657 }
4658 var _task = wrapAsync(task);
4659 return initialParams(function (args, callback) {
4660 function taskFn(cb) {
4661 _task.apply(null, args.concat(cb));
4662 }
4663
4664 if (opts) retry(opts, taskFn, callback);
4665 else retry(taskFn, callback);
4666
4667 });
4668};
4669
4670/**
4671 * Run the functions in the `tasks` collection in series, each one running once
4672 * the previous function has completed. If any functions in the series pass an
4673 * error to its callback, no more functions are run, and `callback` is
4674 * immediately called with the value of the error. Otherwise, `callback`
4675 * receives an array of results when `tasks` have completed.
4676 *
4677 * It is also possible to use an object instead of an array. Each property will
4678 * be run as a function, and the results will be passed to the final `callback`
4679 * as an object instead of an array. This can be a more readable way of handling
4680 * results from {@link async.series}.
4681 *
4682 * **Note** that while many implementations preserve the order of object
4683 * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
4684 * explicitly states that
4685 *
4686 * > The mechanics and order of enumerating the properties is not specified.
4687 *
4688 * So if you rely on the order in which your series of functions are executed,
4689 * and want this to work on all platforms, consider using an array.
4690 *
4691 * @name series
4692 * @static
4693 * @memberOf module:ControlFlow
4694 * @method
4695 * @category Control Flow
4696 * @param {Array|Iterable|Object} tasks - A collection containing
4697 * [async functions]{@link AsyncFunction} to run in series.
4698 * Each function can complete with any number of optional `result` values.
4699 * @param {Function} [callback] - An optional callback to run once all the
4700 * functions have completed. This function gets a results array (or object)
4701 * containing all the result arguments passed to the `task` callbacks. Invoked
4702 * with (err, result).
4703 * @example
4704 * async.series([
4705 * function(callback) {
4706 * // do some stuff ...
4707 * callback(null, 'one');
4708 * },
4709 * function(callback) {
4710 * // do some more stuff ...
4711 * callback(null, 'two');
4712 * }
4713 * ],
4714 * // optional callback
4715 * function(err, results) {
4716 * // results is now equal to ['one', 'two']
4717 * });
4718 *
4719 * async.series({
4720 * one: function(callback) {
4721 * setTimeout(function() {
4722 * callback(null, 1);
4723 * }, 200);
4724 * },
4725 * two: function(callback){
4726 * setTimeout(function() {
4727 * callback(null, 2);
4728 * }, 100);
4729 * }
4730 * }, function(err, results) {
4731 * // results is now equal to: {one: 1, two: 2}
4732 * });
4733 */
4734function series(tasks, callback) {
4735 _parallel(eachOfSeries, tasks, callback);
4736}
4737
4738/**
4739 * Returns `true` if at least one element in the `coll` satisfies an async test.
4740 * If any iteratee call returns `true`, the main `callback` is immediately
4741 * called.
4742 *
4743 * @name some
4744 * @static
4745 * @memberOf module:Collections
4746 * @method
4747 * @alias any
4748 * @category Collection
4749 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4750 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4751 * in the collections in parallel.
4752 * The iteratee should complete with a boolean `result` value.
4753 * Invoked with (item, callback).
4754 * @param {Function} [callback] - A callback which is called as soon as any
4755 * iteratee returns `true`, or after all the iteratee functions have finished.
4756 * Result will be either `true` or `false` depending on the values of the async
4757 * tests. Invoked with (err, result).
4758 * @example
4759 *
4760 * async.some(['file1','file2','file3'], function(filePath, callback) {
4761 * fs.access(filePath, function(err) {
4762 * callback(null, !err)
4763 * });
4764 * }, function(err, result) {
4765 * // if result is true then at least one of the files exists
4766 * });
4767 */
4768var some = doParallel(_createTester(Boolean, identity));
4769
4770/**
4771 * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
4772 *
4773 * @name someLimit
4774 * @static
4775 * @memberOf module:Collections
4776 * @method
4777 * @see [async.some]{@link module:Collections.some}
4778 * @alias anyLimit
4779 * @category Collection
4780 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4781 * @param {number} limit - The maximum number of async operations at a time.
4782 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4783 * in the collections in parallel.
4784 * The iteratee should complete with a boolean `result` value.
4785 * Invoked with (item, callback).
4786 * @param {Function} [callback] - A callback which is called as soon as any
4787 * iteratee returns `true`, or after all the iteratee functions have finished.
4788 * Result will be either `true` or `false` depending on the values of the async
4789 * tests. Invoked with (err, result).
4790 */
4791var someLimit = doParallelLimit(_createTester(Boolean, identity));
4792
4793/**
4794 * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
4795 *
4796 * @name someSeries
4797 * @static
4798 * @memberOf module:Collections
4799 * @method
4800 * @see [async.some]{@link module:Collections.some}
4801 * @alias anySeries
4802 * @category Collection
4803 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4804 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4805 * in the collections in series.
4806 * The iteratee should complete with a boolean `result` value.
4807 * Invoked with (item, callback).
4808 * @param {Function} [callback] - A callback which is called as soon as any
4809 * iteratee returns `true`, or after all the iteratee functions have finished.
4810 * Result will be either `true` or `false` depending on the values of the async
4811 * tests. Invoked with (err, result).
4812 */
4813var someSeries = doLimit(someLimit, 1);
4814
4815/**
4816 * Sorts a list by the results of running each `coll` value through an async
4817 * `iteratee`.
4818 *
4819 * @name sortBy
4820 * @static
4821 * @memberOf module:Collections
4822 * @method
4823 * @category Collection
4824 * @param {Array|Iterable|Object} coll - A collection to iterate over.
4825 * @param {AsyncFunction} iteratee - An async function to apply to each item in
4826 * `coll`.
4827 * The iteratee should complete with a value to use as the sort criteria as
4828 * its `result`.
4829 * Invoked with (item, callback).
4830 * @param {Function} callback - A callback which is called after all the
4831 * `iteratee` functions have finished, or an error occurs. Results is the items
4832 * from the original `coll` sorted by the values returned by the `iteratee`
4833 * calls. Invoked with (err, results).
4834 * @example
4835 *
4836 * async.sortBy(['file1','file2','file3'], function(file, callback) {
4837 * fs.stat(file, function(err, stats) {
4838 * callback(err, stats.mtime);
4839 * });
4840 * }, function(err, results) {
4841 * // results is now the original array of files sorted by
4842 * // modified date
4843 * });
4844 *
4845 * // By modifying the callback parameter the
4846 * // sorting order can be influenced:
4847 *
4848 * // ascending order
4849 * async.sortBy([1,9,3,5], function(x, callback) {
4850 * callback(null, x);
4851 * }, function(err,result) {
4852 * // result callback
4853 * });
4854 *
4855 * // descending order
4856 * async.sortBy([1,9,3,5], function(x, callback) {
4857 * callback(null, x*-1); //<- x*-1 instead of x, turns the order around
4858 * }, function(err,result) {
4859 * // result callback
4860 * });
4861 */
4862function sortBy (coll, iteratee, callback) {
4863 var _iteratee = wrapAsync(iteratee);
4864 map(coll, function (x, callback) {
4865 _iteratee(x, function (err, criteria) {
4866 if (err) return callback(err);
4867 callback(null, {value: x, criteria: criteria});
4868 });
4869 }, function (err, results) {
4870 if (err) return callback(err);
4871 callback(null, arrayMap(results.sort(comparator), baseProperty('value')));
4872 });
4873
4874 function comparator(left, right) {
4875 var a = left.criteria, b = right.criteria;
4876 return a < b ? -1 : a > b ? 1 : 0;
4877 }
4878}
4879
4880/**
4881 * Sets a time limit on an asynchronous function. If the function does not call
4882 * its callback within the specified milliseconds, it will be called with a
4883 * timeout error. The code property for the error object will be `'ETIMEDOUT'`.
4884 *
4885 * @name timeout
4886 * @static
4887 * @memberOf module:Utils
4888 * @method
4889 * @category Util
4890 * @param {AsyncFunction} asyncFn - The async function to limit in time.
4891 * @param {number} milliseconds - The specified time limit.
4892 * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
4893 * to timeout Error for more information..
4894 * @returns {AsyncFunction} Returns a wrapped function that can be used with any
4895 * of the control flow functions.
4896 * Invoke this function with the same parameters as you would `asyncFunc`.
4897 * @example
4898 *
4899 * function myFunction(foo, callback) {
4900 * doAsyncTask(foo, function(err, data) {
4901 * // handle errors
4902 * if (err) return callback(err);
4903 *
4904 * // do some stuff ...
4905 *
4906 * // return processed data
4907 * return callback(null, data);
4908 * });
4909 * }
4910 *
4911 * var wrapped = async.timeout(myFunction, 1000);
4912 *
4913 * // call `wrapped` as you would `myFunction`
4914 * wrapped({ bar: 'bar' }, function(err, data) {
4915 * // if `myFunction` takes < 1000 ms to execute, `err`
4916 * // and `data` will have their expected values
4917 *
4918 * // else `err` will be an Error with the code 'ETIMEDOUT'
4919 * });
4920 */
4921function timeout(asyncFn, milliseconds, info) {
4922 var fn = wrapAsync(asyncFn);
4923
4924 return initialParams(function (args, callback) {
4925 var timedOut = false;
4926 var timer;
4927
4928 function timeoutCallback() {
4929 var name = asyncFn.name || 'anonymous';
4930 var error = new Error('Callback function "' + name + '" timed out.');
4931 error.code = 'ETIMEDOUT';
4932 if (info) {
4933 error.info = info;
4934 }
4935 timedOut = true;
4936 callback(error);
4937 }
4938
4939 args.push(function () {
4940 if (!timedOut) {
4941 callback.apply(null, arguments);
4942 clearTimeout(timer);
4943 }
4944 });
4945
4946 // setup timer and call original function
4947 timer = setTimeout(timeoutCallback, milliseconds);
4948 fn.apply(null, args);
4949 });
4950}
4951
4952/* Built-in method references for those with the same name as other `lodash` methods. */
4953var nativeCeil = Math.ceil;
4954var nativeMax = Math.max;
4955
4956/**
4957 * The base implementation of `_.range` and `_.rangeRight` which doesn't
4958 * coerce arguments.
4959 *
4960 * @private
4961 * @param {number} start The start of the range.
4962 * @param {number} end The end of the range.
4963 * @param {number} step The value to increment or decrement by.
4964 * @param {boolean} [fromRight] Specify iterating from right to left.
4965 * @returns {Array} Returns the range of numbers.
4966 */
4967function baseRange(start, end, step, fromRight) {
4968 var index = -1,
4969 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
4970 result = Array(length);
4971
4972 while (length--) {
4973 result[fromRight ? length : ++index] = start;
4974 start += step;
4975 }
4976 return result;
4977}
4978
4979/**
4980 * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
4981 * time.
4982 *
4983 * @name timesLimit
4984 * @static
4985 * @memberOf module:ControlFlow
4986 * @method
4987 * @see [async.times]{@link module:ControlFlow.times}
4988 * @category Control Flow
4989 * @param {number} count - The number of times to run the function.
4990 * @param {number} limit - The maximum number of async operations at a time.
4991 * @param {AsyncFunction} iteratee - The async function to call `n` times.
4992 * Invoked with the iteration index and a callback: (n, next).
4993 * @param {Function} callback - see [async.map]{@link module:Collections.map}.
4994 */
4995function timeLimit(count, limit, iteratee, callback) {
4996 var _iteratee = wrapAsync(iteratee);
4997 mapLimit(baseRange(0, count, 1), limit, _iteratee, callback);
4998}
4999
5000/**
5001 * Calls the `iteratee` function `n` times, and accumulates results in the same
5002 * manner you would use with [map]{@link module:Collections.map}.
5003 *
5004 * @name times
5005 * @static
5006 * @memberOf module:ControlFlow
5007 * @method
5008 * @see [async.map]{@link module:Collections.map}
5009 * @category Control Flow
5010 * @param {number} n - The number of times to run the function.
5011 * @param {AsyncFunction} iteratee - The async function to call `n` times.
5012 * Invoked with the iteration index and a callback: (n, next).
5013 * @param {Function} callback - see {@link module:Collections.map}.
5014 * @example
5015 *
5016 * // Pretend this is some complicated async factory
5017 * var createUser = function(id, callback) {
5018 * callback(null, {
5019 * id: 'user' + id
5020 * });
5021 * };
5022 *
5023 * // generate 5 users
5024 * async.times(5, function(n, next) {
5025 * createUser(n, function(err, user) {
5026 * next(err, user);
5027 * });
5028 * }, function(err, users) {
5029 * // we should now have 5 users
5030 * });
5031 */
5032var times = doLimit(timeLimit, Infinity);
5033
5034/**
5035 * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.
5036 *
5037 * @name timesSeries
5038 * @static
5039 * @memberOf module:ControlFlow
5040 * @method
5041 * @see [async.times]{@link module:ControlFlow.times}
5042 * @category Control Flow
5043 * @param {number} n - The number of times to run the function.
5044 * @param {AsyncFunction} iteratee - The async function to call `n` times.
5045 * Invoked with the iteration index and a callback: (n, next).
5046 * @param {Function} callback - see {@link module:Collections.map}.
5047 */
5048var timesSeries = doLimit(timeLimit, 1);
5049
5050/**
5051 * A relative of `reduce`. Takes an Object or Array, and iterates over each
5052 * element in series, each step potentially mutating an `accumulator` value.
5053 * The type of the accumulator defaults to the type of collection passed in.
5054 *
5055 * @name transform
5056 * @static
5057 * @memberOf module:Collections
5058 * @method
5059 * @category Collection
5060 * @param {Array|Iterable|Object} coll - A collection to iterate over.
5061 * @param {*} [accumulator] - The initial state of the transform. If omitted,
5062 * it will default to an empty Object or Array, depending on the type of `coll`
5063 * @param {AsyncFunction} iteratee - A function applied to each item in the
5064 * collection that potentially modifies the accumulator.
5065 * Invoked with (accumulator, item, key, callback).
5066 * @param {Function} [callback] - A callback which is called after all the
5067 * `iteratee` functions have finished. Result is the transformed accumulator.
5068 * Invoked with (err, result).
5069 * @example
5070 *
5071 * async.transform([1,2,3], function(acc, item, index, callback) {
5072 * // pointless async:
5073 * process.nextTick(function() {
5074 * acc.push(item * 2)
5075 * callback(null)
5076 * });
5077 * }, function(err, result) {
5078 * // result is now equal to [2, 4, 6]
5079 * });
5080 *
5081 * @example
5082 *
5083 * async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) {
5084 * setImmediate(function () {
5085 * obj[key] = val * 2;
5086 * callback();
5087 * })
5088 * }, function (err, result) {
5089 * // result is equal to {a: 2, b: 4, c: 6}
5090 * })
5091 */
5092function transform (coll, accumulator, iteratee, callback) {
5093 if (arguments.length <= 3) {
5094 callback = iteratee;
5095 iteratee = accumulator;
5096 accumulator = isArray(coll) ? [] : {};
5097 }
5098 callback = once(callback || noop);
5099 var _iteratee = wrapAsync(iteratee);
5100
5101 eachOf(coll, function(v, k, cb) {
5102 _iteratee(accumulator, v, k, cb);
5103 }, function(err) {
5104 callback(err, accumulator);
5105 });
5106}
5107
5108/**
5109 * It runs each task in series but stops whenever any of the functions were
5110 * successful. If one of the tasks were successful, the `callback` will be
5111 * passed the result of the successful task. If all tasks fail, the callback
5112 * will be passed the error and result (if any) of the final attempt.
5113 *
5114 * @name tryEach
5115 * @static
5116 * @memberOf module:ControlFlow
5117 * @method
5118 * @category Control Flow
5119 * @param {Array|Iterable|Object} tasks - A collection containing functions to
5120 * run, each function is passed a `callback(err, result)` it must call on
5121 * completion with an error `err` (which can be `null`) and an optional `result`
5122 * value.
5123 * @param {Function} [callback] - An optional callback which is called when one
5124 * of the tasks has succeeded, or all have failed. It receives the `err` and
5125 * `result` arguments of the last attempt at completing the `task`. Invoked with
5126 * (err, results).
5127 * @example
5128 * async.tryEach([
5129 * function getDataFromFirstWebsite(callback) {
5130 * // Try getting the data from the first website
5131 * callback(err, data);
5132 * },
5133 * function getDataFromSecondWebsite(callback) {
5134 * // First website failed,
5135 * // Try getting the data from the backup website
5136 * callback(err, data);
5137 * }
5138 * ],
5139 * // optional callback
5140 * function(err, results) {
5141 * Now do something with the data.
5142 * });
5143 *
5144 */
5145function tryEach(tasks, callback) {
5146 var error = null;
5147 var result;
5148 callback = callback || noop;
5149 eachSeries(tasks, function(task, callback) {
5150 wrapAsync(task)(function (err, res/*, ...args*/) {
5151 if (arguments.length > 2) {
5152 result = slice(arguments, 1);
5153 } else {
5154 result = res;
5155 }
5156 error = err;
5157 callback(!err);
5158 });
5159 }, function () {
5160 callback(error, result);
5161 });
5162}
5163
5164/**
5165 * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,
5166 * unmemoized form. Handy for testing.
5167 *
5168 * @name unmemoize
5169 * @static
5170 * @memberOf module:Utils
5171 * @method
5172 * @see [async.memoize]{@link module:Utils.memoize}
5173 * @category Util
5174 * @param {AsyncFunction} fn - the memoized function
5175 * @returns {AsyncFunction} a function that calls the original unmemoized function
5176 */
5177function unmemoize(fn) {
5178 return function () {
5179 return (fn.unmemoized || fn).apply(null, arguments);
5180 };
5181}
5182
5183/**
5184 * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
5185 * stopped, or an error occurs.
5186 *
5187 * @name whilst
5188 * @static
5189 * @memberOf module:ControlFlow
5190 * @method
5191 * @category Control Flow
5192 * @param {Function} test - synchronous truth test to perform before each
5193 * execution of `iteratee`. Invoked with ().
5194 * @param {AsyncFunction} iteratee - An async function which is called each time
5195 * `test` passes. Invoked with (callback).
5196 * @param {Function} [callback] - A callback which is called after the test
5197 * function has failed and repeated execution of `iteratee` has stopped. `callback`
5198 * will be passed an error and any arguments passed to the final `iteratee`'s
5199 * callback. Invoked with (err, [results]);
5200 * @returns undefined
5201 * @example
5202 *
5203 * var count = 0;
5204 * async.whilst(
5205 * function() { return count < 5; },
5206 * function(callback) {
5207 * count++;
5208 * setTimeout(function() {
5209 * callback(null, count);
5210 * }, 1000);
5211 * },
5212 * function (err, n) {
5213 * // 5 seconds have passed, n = 5
5214 * }
5215 * );
5216 */
5217function whilst(test, iteratee, callback) {
5218 callback = onlyOnce(callback || noop);
5219 var _iteratee = wrapAsync(iteratee);
5220 if (!test()) return callback(null);
5221 var next = function(err/*, ...args*/) {
5222 if (err) return callback(err);
5223 if (test()) return _iteratee(next);
5224 var args = slice(arguments, 1);
5225 callback.apply(null, [null].concat(args));
5226 };
5227 _iteratee(next);
5228}
5229
5230/**
5231 * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
5232 * stopped, or an error occurs. `callback` will be passed an error and any
5233 * arguments passed to the final `iteratee`'s callback.
5234 *
5235 * The inverse of [whilst]{@link module:ControlFlow.whilst}.
5236 *
5237 * @name until
5238 * @static
5239 * @memberOf module:ControlFlow
5240 * @method
5241 * @see [async.whilst]{@link module:ControlFlow.whilst}
5242 * @category Control Flow
5243 * @param {Function} test - synchronous truth test to perform before each
5244 * execution of `iteratee`. Invoked with ().
5245 * @param {AsyncFunction} iteratee - An async function which is called each time
5246 * `test` fails. Invoked with (callback).
5247 * @param {Function} [callback] - A callback which is called after the test
5248 * function has passed and repeated execution of `iteratee` has stopped. `callback`
5249 * will be passed an error and any arguments passed to the final `iteratee`'s
5250 * callback. Invoked with (err, [results]);
5251 */
5252function until(test, iteratee, callback) {
5253 whilst(function() {
5254 return !test.apply(this, arguments);
5255 }, iteratee, callback);
5256}
5257
5258/**
5259 * Runs the `tasks` array of functions in series, each passing their results to
5260 * the next in the array. However, if any of the `tasks` pass an error to their
5261 * own callback, the next function is not executed, and the main `callback` is
5262 * immediately called with the error.
5263 *
5264 * @name waterfall
5265 * @static
5266 * @memberOf module:ControlFlow
5267 * @method
5268 * @category Control Flow
5269 * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
5270 * to run.
5271 * Each function should complete with any number of `result` values.
5272 * The `result` values will be passed as arguments, in order, to the next task.
5273 * @param {Function} [callback] - An optional callback to run once all the
5274 * functions have completed. This will be passed the results of the last task's
5275 * callback. Invoked with (err, [results]).
5276 * @returns undefined
5277 * @example
5278 *
5279 * async.waterfall([
5280 * function(callback) {
5281 * callback(null, 'one', 'two');
5282 * },
5283 * function(arg1, arg2, callback) {
5284 * // arg1 now equals 'one' and arg2 now equals 'two'
5285 * callback(null, 'three');
5286 * },
5287 * function(arg1, callback) {
5288 * // arg1 now equals 'three'
5289 * callback(null, 'done');
5290 * }
5291 * ], function (err, result) {
5292 * // result now equals 'done'
5293 * });
5294 *
5295 * // Or, with named functions:
5296 * async.waterfall([
5297 * myFirstFunction,
5298 * mySecondFunction,
5299 * myLastFunction,
5300 * ], function (err, result) {
5301 * // result now equals 'done'
5302 * });
5303 * function myFirstFunction(callback) {
5304 * callback(null, 'one', 'two');
5305 * }
5306 * function mySecondFunction(arg1, arg2, callback) {
5307 * // arg1 now equals 'one' and arg2 now equals 'two'
5308 * callback(null, 'three');
5309 * }
5310 * function myLastFunction(arg1, callback) {
5311 * // arg1 now equals 'three'
5312 * callback(null, 'done');
5313 * }
5314 */
5315var waterfall = function(tasks, callback) {
5316 callback = once(callback || noop);
5317 if (!isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
5318 if (!tasks.length) return callback();
5319 var taskIndex = 0;
5320
5321 function nextTask(args) {
5322 var task = wrapAsync(tasks[taskIndex++]);
5323 args.push(onlyOnce(next));
5324 task.apply(null, args);
5325 }
5326
5327 function next(err/*, ...args*/) {
5328 if (err || taskIndex === tasks.length) {
5329 return callback.apply(null, arguments);
5330 }
5331 nextTask(slice(arguments, 1));
5332 }
5333
5334 nextTask([]);
5335};
5336
5337/**
5338 * An "async function" in the context of Async is an asynchronous function with
5339 * a variable number of parameters, with the final parameter being a callback.
5340 * (`function (arg1, arg2, ..., callback) {}`)
5341 * The final callback is of the form `callback(err, results...)`, which must be
5342 * called once the function is completed. The callback should be called with a
5343 * Error as its first argument to signal that an error occurred.
5344 * Otherwise, if no error occurred, it should be called with `null` as the first
5345 * argument, and any additional `result` arguments that may apply, to signal
5346 * successful completion.
5347 * The callback must be called exactly once, ideally on a later tick of the
5348 * JavaScript event loop.
5349 *
5350 * This type of function is also referred to as a "Node-style async function",
5351 * or a "continuation passing-style function" (CPS). Most of the methods of this
5352 * library are themselves CPS/Node-style async functions, or functions that
5353 * return CPS/Node-style async functions.
5354 *
5355 * Wherever we accept a Node-style async function, we also directly accept an
5356 * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
5357 * In this case, the `async` function will not be passed a final callback
5358 * argument, and any thrown error will be used as the `err` argument of the
5359 * implicit callback, and the return value will be used as the `result` value.
5360 * (i.e. a `rejected` of the returned Promise becomes the `err` callback
5361 * argument, and a `resolved` value becomes the `result`.)
5362 *
5363 * Note, due to JavaScript limitations, we can only detect native `async`
5364 * functions and not transpilied implementations.
5365 * Your environment must have `async`/`await` support for this to work.
5366 * (e.g. Node > v7.6, or a recent version of a modern browser).
5367 * If you are using `async` functions through a transpiler (e.g. Babel), you
5368 * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
5369 * because the `async function` will be compiled to an ordinary function that
5370 * returns a promise.
5371 *
5372 * @typedef {Function} AsyncFunction
5373 * @static
5374 */
5375
5376/**
5377 * Async is a utility module which provides straight-forward, powerful functions
5378 * for working with asynchronous JavaScript. Although originally designed for
5379 * use with [Node.js](http://nodejs.org) and installable via
5380 * `npm install --save async`, it can also be used directly in the browser.
5381 * @module async
5382 * @see AsyncFunction
5383 */
5384
5385
5386/**
5387 * A collection of `async` functions for manipulating collections, such as
5388 * arrays and objects.
5389 * @module Collections
5390 */
5391
5392/**
5393 * A collection of `async` functions for controlling the flow through a script.
5394 * @module ControlFlow
5395 */
5396
5397/**
5398 * A collection of `async` utility functions.
5399 * @module Utils
5400 */
5401
5402var index = {
5403 apply: apply,
5404 applyEach: applyEach,
5405 applyEachSeries: applyEachSeries,
5406 asyncify: asyncify,
5407 auto: auto,
5408 autoInject: autoInject,
5409 cargo: cargo,
5410 compose: compose,
5411 concat: concat,
5412 concatLimit: concatLimit,
5413 concatSeries: concatSeries,
5414 constant: constant,
5415 detect: detect,
5416 detectLimit: detectLimit,
5417 detectSeries: detectSeries,
5418 dir: dir,
5419 doDuring: doDuring,
5420 doUntil: doUntil,
5421 doWhilst: doWhilst,
5422 during: during,
5423 each: eachLimit,
5424 eachLimit: eachLimit$1,
5425 eachOf: eachOf,
5426 eachOfLimit: eachOfLimit,
5427 eachOfSeries: eachOfSeries,
5428 eachSeries: eachSeries,
5429 ensureAsync: ensureAsync,
5430 every: every,
5431 everyLimit: everyLimit,
5432 everySeries: everySeries,
5433 filter: filter,
5434 filterLimit: filterLimit,
5435 filterSeries: filterSeries,
5436 forever: forever,
5437 groupBy: groupBy,
5438 groupByLimit: groupByLimit,
5439 groupBySeries: groupBySeries,
5440 log: log,
5441 map: map,
5442 mapLimit: mapLimit,
5443 mapSeries: mapSeries,
5444 mapValues: mapValues,
5445 mapValuesLimit: mapValuesLimit,
5446 mapValuesSeries: mapValuesSeries,
5447 memoize: memoize,
5448 nextTick: nextTick,
5449 parallel: parallelLimit,
5450 parallelLimit: parallelLimit$1,
5451 priorityQueue: priorityQueue,
5452 queue: queue$1,
5453 race: race,
5454 reduce: reduce,
5455 reduceRight: reduceRight,
5456 reflect: reflect,
5457 reflectAll: reflectAll,
5458 reject: reject,
5459 rejectLimit: rejectLimit,
5460 rejectSeries: rejectSeries,
5461 retry: retry,
5462 retryable: retryable,
5463 seq: seq,
5464 series: series,
5465 setImmediate: setImmediate$1,
5466 some: some,
5467 someLimit: someLimit,
5468 someSeries: someSeries,
5469 sortBy: sortBy,
5470 timeout: timeout,
5471 times: times,
5472 timesLimit: timeLimit,
5473 timesSeries: timesSeries,
5474 transform: transform,
5475 tryEach: tryEach,
5476 unmemoize: unmemoize,
5477 until: until,
5478 waterfall: waterfall,
5479 whilst: whilst,
5480
5481 // aliases
5482 all: every,
5483 allLimit: everyLimit,
5484 allSeries: everySeries,
5485 any: some,
5486 anyLimit: someLimit,
5487 anySeries: someSeries,
5488 find: detect,
5489 findLimit: detectLimit,
5490 findSeries: detectSeries,
5491 forEach: eachLimit,
5492 forEachSeries: eachSeries,
5493 forEachLimit: eachLimit$1,
5494 forEachOf: eachOf,
5495 forEachOfSeries: eachOfSeries,
5496 forEachOfLimit: eachOfLimit,
5497 inject: reduce,
5498 foldl: reduce,
5499 foldr: reduceRight,
5500 select: filter,
5501 selectLimit: filterLimit,
5502 selectSeries: filterSeries,
5503 wrapSync: asyncify
5504};
5505
5506exports['default'] = index;
5507exports.apply = apply;
5508exports.applyEach = applyEach;
5509exports.applyEachSeries = applyEachSeries;
5510exports.asyncify = asyncify;
5511exports.auto = auto;
5512exports.autoInject = autoInject;
5513exports.cargo = cargo;
5514exports.compose = compose;
5515exports.concat = concat;
5516exports.concatLimit = concatLimit;
5517exports.concatSeries = concatSeries;
5518exports.constant = constant;
5519exports.detect = detect;
5520exports.detectLimit = detectLimit;
5521exports.detectSeries = detectSeries;
5522exports.dir = dir;
5523exports.doDuring = doDuring;
5524exports.doUntil = doUntil;
5525exports.doWhilst = doWhilst;
5526exports.during = during;
5527exports.each = eachLimit;
5528exports.eachLimit = eachLimit$1;
5529exports.eachOf = eachOf;
5530exports.eachOfLimit = eachOfLimit;
5531exports.eachOfSeries = eachOfSeries;
5532exports.eachSeries = eachSeries;
5533exports.ensureAsync = ensureAsync;
5534exports.every = every;
5535exports.everyLimit = everyLimit;
5536exports.everySeries = everySeries;
5537exports.filter = filter;
5538exports.filterLimit = filterLimit;
5539exports.filterSeries = filterSeries;
5540exports.forever = forever;
5541exports.groupBy = groupBy;
5542exports.groupByLimit = groupByLimit;
5543exports.groupBySeries = groupBySeries;
5544exports.log = log;
5545exports.map = map;
5546exports.mapLimit = mapLimit;
5547exports.mapSeries = mapSeries;
5548exports.mapValues = mapValues;
5549exports.mapValuesLimit = mapValuesLimit;
5550exports.mapValuesSeries = mapValuesSeries;
5551exports.memoize = memoize;
5552exports.nextTick = nextTick;
5553exports.parallel = parallelLimit;
5554exports.parallelLimit = parallelLimit$1;
5555exports.priorityQueue = priorityQueue;
5556exports.queue = queue$1;
5557exports.race = race;
5558exports.reduce = reduce;
5559exports.reduceRight = reduceRight;
5560exports.reflect = reflect;
5561exports.reflectAll = reflectAll;
5562exports.reject = reject;
5563exports.rejectLimit = rejectLimit;
5564exports.rejectSeries = rejectSeries;
5565exports.retry = retry;
5566exports.retryable = retryable;
5567exports.seq = seq;
5568exports.series = series;
5569exports.setImmediate = setImmediate$1;
5570exports.some = some;
5571exports.someLimit = someLimit;
5572exports.someSeries = someSeries;
5573exports.sortBy = sortBy;
5574exports.timeout = timeout;
5575exports.times = times;
5576exports.timesLimit = timeLimit;
5577exports.timesSeries = timesSeries;
5578exports.transform = transform;
5579exports.tryEach = tryEach;
5580exports.unmemoize = unmemoize;
5581exports.until = until;
5582exports.waterfall = waterfall;
5583exports.whilst = whilst;
5584exports.all = every;
5585exports.allLimit = everyLimit;
5586exports.allSeries = everySeries;
5587exports.any = some;
5588exports.anyLimit = someLimit;
5589exports.anySeries = someSeries;
5590exports.find = detect;
5591exports.findLimit = detectLimit;
5592exports.findSeries = detectSeries;
5593exports.forEach = eachLimit;
5594exports.forEachSeries = eachSeries;
5595exports.forEachLimit = eachLimit$1;
5596exports.forEachOf = eachOf;
5597exports.forEachOfSeries = eachOfSeries;
5598exports.forEachOfLimit = eachOfLimit;
5599exports.inject = reduce;
5600exports.foldl = reduce;
5601exports.foldr = reduceRight;
5602exports.select = filter;
5603exports.selectLimit = filterLimit;
5604exports.selectSeries = filterSeries;
5605exports.wrapSync = asyncify;
5606
5607Object.defineProperty(exports, '__esModule', { value: true });
5608
5609})));
Note: See TracBrowser for help on using the repository browser.