PluginProbe
WP-Stateless – Google Cloud Storage / 2.2.1
WP-Stateless – Google Cloud Storage v2.2.1
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
wp-stateless / static / scripts / async.js

async.js in WP-Stateless – Google Cloud Storage 2.2.1, at static/scripts/async.js

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