aboutsummaryrefslogtreecommitdiff
path: root/node_modules/async/dist
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/async/dist')
-rw-r--r--node_modules/async/dist/async.js6372
-rw-r--r--node_modules/async/dist/async.min.js4
2 files changed, 1033 insertions, 5343 deletions
diff --git a/node_modules/async/dist/async.js b/node_modules/async/dist/async.js
index c4fbcef46..31e7620fb 100644
--- a/node_modules/async/dist/async.js
+++ b/node_modules/async/dist/async.js
@@ -1,5575 +1,1265 @@
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.async = global.async || {})));
-}(this, (function (exports) { 'use strict';
-
-function slice(arrayLike, start) {
- start = start|0;
- var newLen = Math.max(arrayLike.length - start, 0);
- var newArr = Array(newLen);
- for(var idx = 0; idx < newLen; idx++) {
- newArr[idx] = arrayLike[start + idx];
- }
- return newArr;
-}
-
-var initialParams = function (fn) {
- return function (/*...args, callback*/) {
- var args = slice(arguments);
- var callback = args.pop();
- fn.call(this, args, callback);
- };
-};
-
-/**
- * Checks if `value` is the
- * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
- * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(_.noop);
- * // => true
- *
- * _.isObject(null);
- * // => false
- */
-function isObject(value) {
- var type = typeof value;
- return value != null && (type == 'object' || type == 'function');
-}
-
-var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
-var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
-
-function fallback(fn) {
- setTimeout(fn, 0);
-}
-
-function wrap(defer) {
- return function (fn/*, ...args*/) {
- var args = slice(arguments, 1);
- defer(function () {
- fn.apply(null, args);
- });
- };
-}
-
-var _defer;
-
-if (hasSetImmediate) {
- _defer = setImmediate;
-} else if (hasNextTick) {
- _defer = process.nextTick;
-} else {
- _defer = fallback;
-}
-
-var setImmediate$1 = wrap(_defer);
-
-/**
- * Take a sync function and make it async, passing its return value to a
- * callback. This is useful for plugging sync functions into a waterfall,
- * series, or other async functions. Any arguments passed to the generated
- * function will be passed to the wrapped function (except for the final
- * callback argument). Errors thrown will be passed to the callback.
- *
- * If the function passed to `asyncify` returns a Promise, that promises's
- * resolved/rejected state will be used to call the callback, rather than simply
- * the synchronous return value.
- *
- * This also means you can asyncify ES2017 `async` functions.
- *
- * @name asyncify
- * @static
- * @memberOf module:Utils
- * @method
- * @alias wrapSync
- * @category Util
- * @param {Function} func - The synchronous function, or Promise-returning
- * function to convert to an {@link AsyncFunction}.
- * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
- * invoked with `(args..., callback)`.
- * @example
- *
- * // passing a regular synchronous function
- * async.waterfall([
- * async.apply(fs.readFile, filename, "utf8"),
- * async.asyncify(JSON.parse),
- * function (data, next) {
- * // data is the result of parsing the text.
- * // If there was a parsing error, it would have been caught.
- * }
- * ], callback);
+/*!
+ * async
+ * https://github.com/caolan/async
*
- * // passing a function returning a promise
- * async.waterfall([
- * async.apply(fs.readFile, filename, "utf8"),
- * async.asyncify(function (contents) {
- * return db.model.create(contents);
- * }),
- * function (model, next) {
- * // `model` is the instantiated model object.
- * // If there was an error, this function would be skipped.
- * }
- * ], callback);
- *
- * // es2017 example, though `asyncify` is not needed if your JS environment
- * // supports async functions out of the box
- * var q = async.queue(async.asyncify(async function(file) {
- * var intermediateStep = await processFile(file);
- * return await somePromise(intermediateStep)
- * }));
- *
- * q.push(files);
+ * Copyright 2010-2014 Caolan McMahon
+ * Released under the MIT license
*/
-function asyncify(func) {
- return initialParams(function (args, callback) {
- var result;
- try {
- result = func.apply(this, args);
- } catch (e) {
- return callback(e);
- }
- // if result is Promise object
- if (isObject(result) && typeof result.then === 'function') {
- result.then(function(value) {
- invokeCallback(callback, null, value);
- }, function(err) {
- invokeCallback(callback, err.message ? err : new Error(err));
- });
- } else {
- callback(null, result);
- }
- });
-}
+(function () {
-function invokeCallback(callback, error, value) {
- try {
- callback(error, value);
- } catch (e) {
- setImmediate$1(rethrow, e);
+ var async = {};
+ function noop() {}
+ function identity(v) {
+ return v;
+ }
+ function toBool(v) {
+ return !!v;
+ }
+ function notId(v) {
+ return !v;
}
-}
-
-function rethrow(error) {
- throw error;
-}
-var supportsSymbol = typeof Symbol === 'function';
+ // global on the server, window in the browser
+ var previous_async;
-function isAsync(fn) {
- return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction';
-}
+ // Establish the root object, `window` (`self`) in the browser, `global`
+ // on the server, or `this` in some virtual machines. We use `self`
+ // instead of `window` for `WebWorker` support.
+ var root = typeof self === 'object' && self.self === self && self ||
+ typeof global === 'object' && global.global === global && global ||
+ this;
-function wrapAsync(asyncFn) {
- return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
-}
+ if (root != null) {
+ previous_async = root.async;
+ }
-function applyEach$1(eachfn) {
- return function(fns/*, ...args*/) {
- var args = slice(arguments, 1);
- var go = initialParams(function(args, callback) {
- var that = this;
- return eachfn(fns, function (fn, cb) {
- wrapAsync(fn).apply(that, args.concat(cb));
- }, callback);
- });
- if (args.length) {
- return go.apply(this, args);
- }
- else {
- return go;
- }
+ async.noConflict = function () {
+ root.async = previous_async;
+ return async;
};
-}
-/** Detect free variable `global` from Node.js. */
-var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
-
-/** Detect free variable `self`. */
-var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
-
-/** Used as a reference to the global object. */
-var root = freeGlobal || freeSelf || Function('return this')();
-
-/** Built-in value references. */
-var Symbol$1 = root.Symbol;
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Used to resolve the
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
- * of values.
- */
-var nativeObjectToString = objectProto.toString;
-
-/** Built-in value references. */
-var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
-
-/**
- * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
- *
- * @private
- * @param {*} value The value to query.
- * @returns {string} Returns the raw `toStringTag`.
- */
-function getRawTag(value) {
- var isOwn = hasOwnProperty.call(value, symToStringTag$1),
- tag = value[symToStringTag$1];
-
- try {
- value[symToStringTag$1] = undefined;
- var unmasked = true;
- } catch (e) {}
-
- var result = nativeObjectToString.call(value);
- if (unmasked) {
- if (isOwn) {
- value[symToStringTag$1] = tag;
- } else {
- delete value[symToStringTag$1];
+ function only_once(fn) {
+ return function() {
+ if (fn === null) throw new Error("Callback was already called.");
+ fn.apply(this, arguments);
+ fn = null;
+ };
}
- }
- return result;
-}
-
-/** Used for built-in method references. */
-var objectProto$1 = Object.prototype;
-
-/**
- * Used to resolve the
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
- * of values.
- */
-var nativeObjectToString$1 = objectProto$1.toString;
-
-/**
- * Converts `value` to a string using `Object.prototype.toString`.
- *
- * @private
- * @param {*} value The value to convert.
- * @returns {string} Returns the converted string.
- */
-function objectToString(value) {
- return nativeObjectToString$1.call(value);
-}
-/** `Object#toString` result references. */
-var nullTag = '[object Null]';
-var undefinedTag = '[object Undefined]';
-
-/** Built-in value references. */
-var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
+ function _once(fn) {
+ return function() {
+ if (fn === null) return;
+ fn.apply(this, arguments);
+ fn = null;
+ };
+ }
-/**
- * The base implementation of `getTag` without fallbacks for buggy environments.
- *
- * @private
- * @param {*} value The value to query.
- * @returns {string} Returns the `toStringTag`.
- */
-function baseGetTag(value) {
- if (value == null) {
- return value === undefined ? undefinedTag : nullTag;
- }
- value = Object(value);
- return (symToStringTag && symToStringTag in value)
- ? getRawTag(value)
- : objectToString(value);
-}
-
-/** `Object#toString` result references. */
-var asyncTag = '[object AsyncFunction]';
-var funcTag = '[object Function]';
-var genTag = '[object GeneratorFunction]';
-var proxyTag = '[object Proxy]';
-
-/**
- * Checks if `value` is classified as a `Function` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a function, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- *
- * _.isFunction(/abc/);
- * // => false
- */
-function isFunction(value) {
- if (!isObject(value)) {
- return false;
- }
- // The use of `Object#toString` avoids issues with the `typeof` operator
- // in Safari 9 which returns 'object' for typed arrays and other constructors.
- var tag = baseGetTag(value);
- return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
-}
-
-/** Used as references for various `Number` constants. */
-var MAX_SAFE_INTEGER = 9007199254740991;
-
-/**
- * Checks if `value` is a valid array-like length.
- *
- * **Note:** This method is loosely based on
- * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
- * @example
- *
- * _.isLength(3);
- * // => true
- *
- * _.isLength(Number.MIN_VALUE);
- * // => false
- *
- * _.isLength(Infinity);
- * // => false
- *
- * _.isLength('3');
- * // => false
- */
-function isLength(value) {
- return typeof value == 'number' &&
- value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
-}
-
-/**
- * Checks if `value` is array-like. A value is considered array-like if it's
- * not a function and has a `value.length` that's an integer greater than or
- * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
- * @example
- *
- * _.isArrayLike([1, 2, 3]);
- * // => true
- *
- * _.isArrayLike(document.body.children);
- * // => true
- *
- * _.isArrayLike('abc');
- * // => true
- *
- * _.isArrayLike(_.noop);
- * // => false
- */
-function isArrayLike(value) {
- return value != null && isLength(value.length) && !isFunction(value);
-}
+ //// cross-browser compatiblity functions ////
-// A temporary value used to identify if the loop should be broken.
-// See #1064, #1293
-var breakLoop = {};
+ var _toString = Object.prototype.toString;
-/**
- * This method returns `undefined`.
- *
- * @static
- * @memberOf _
- * @since 2.3.0
- * @category Util
- * @example
- *
- * _.times(2, _.noop);
- * // => [undefined, undefined]
- */
-function noop() {
- // No operation performed.
-}
-
-function once(fn) {
- return function () {
- if (fn === null) return;
- var callFn = fn;
- fn = null;
- callFn.apply(this, arguments);
+ var _isArray = Array.isArray || function (obj) {
+ return _toString.call(obj) === '[object Array]';
};
-}
-
-var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator;
-
-var getIterator = function (coll) {
- return iteratorSymbol && coll[iteratorSymbol] && coll[iteratorSymbol]();
-};
-
-/**
- * The base implementation of `_.times` without support for iteratee shorthands
- * or max array length checks.
- *
- * @private
- * @param {number} n The number of times to invoke `iteratee`.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the array of results.
- */
-function baseTimes(n, iteratee) {
- var index = -1,
- result = Array(n);
-
- while (++index < n) {
- result[index] = iteratee(index);
- }
- return result;
-}
-
-/**
- * Checks if `value` is object-like. A value is object-like if it's not `null`
- * and has a `typeof` result of "object".
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
- * @example
- *
- * _.isObjectLike({});
- * // => true
- *
- * _.isObjectLike([1, 2, 3]);
- * // => true
- *
- * _.isObjectLike(_.noop);
- * // => false
- *
- * _.isObjectLike(null);
- * // => false
- */
-function isObjectLike(value) {
- return value != null && typeof value == 'object';
-}
-
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]';
-
-/**
- * The base implementation of `_.isArguments`.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an `arguments` object,
- */
-function baseIsArguments(value) {
- return isObjectLike(value) && baseGetTag(value) == argsTag;
-}
-
-/** Used for built-in method references. */
-var objectProto$3 = Object.prototype;
-/** Used to check objects for own properties. */
-var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
-
-/** Built-in value references. */
-var propertyIsEnumerable = objectProto$3.propertyIsEnumerable;
-
-/**
- * Checks if `value` is likely an `arguments` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an `arguments` object,
- * else `false`.
- * @example
- *
- * _.isArguments(function() { return arguments; }());
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
-var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
- return isObjectLike(value) && hasOwnProperty$2.call(value, 'callee') &&
- !propertyIsEnumerable.call(value, 'callee');
-};
-
-/**
- * Checks if `value` is classified as an `Array` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an array, else `false`.
- * @example
- *
- * _.isArray([1, 2, 3]);
- * // => true
- *
- * _.isArray(document.body.children);
- * // => false
- *
- * _.isArray('abc');
- * // => false
- *
- * _.isArray(_.noop);
- * // => false
- */
-var isArray = Array.isArray;
-
-/**
- * This method returns `false`.
- *
- * @static
- * @memberOf _
- * @since 4.13.0
- * @category Util
- * @returns {boolean} Returns `false`.
- * @example
- *
- * _.times(2, _.stubFalse);
- * // => [false, false]
- */
-function stubFalse() {
- return false;
-}
-
-/** Detect free variable `exports`. */
-var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
+ // Ported from underscore.js isObject
+ var _isObject = function(obj) {
+ var type = typeof obj;
+ return type === 'function' || type === 'object' && !!obj;
+ };
-/** Detect free variable `module`. */
-var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
+ function _isArrayLike(arr) {
+ return _isArray(arr) || (
+ // has a positive integer length property
+ typeof arr.length === "number" &&
+ arr.length >= 0 &&
+ arr.length % 1 === 0
+ );
+ }
-/** Detect the popular CommonJS extension `module.exports`. */
-var moduleExports = freeModule && freeModule.exports === freeExports;
+ function _arrayEach(arr, iterator) {
+ var index = -1,
+ length = arr.length;
-/** Built-in value references. */
-var Buffer = moduleExports ? root.Buffer : undefined;
+ while (++index < length) {
+ iterator(arr[index], index, arr);
+ }
+ }
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
+ function _map(arr, iterator) {
+ var index = -1,
+ length = arr.length,
+ result = Array(length);
-/**
- * Checks if `value` is a buffer.
- *
- * @static
- * @memberOf _
- * @since 4.3.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
- * @example
- *
- * _.isBuffer(new Buffer(2));
- * // => true
- *
- * _.isBuffer(new Uint8Array(2));
- * // => false
- */
-var isBuffer = nativeIsBuffer || stubFalse;
-
-/** Used as references for various `Number` constants. */
-var MAX_SAFE_INTEGER$1 = 9007199254740991;
+ while (++index < length) {
+ result[index] = iterator(arr[index], index, arr);
+ }
+ return result;
+ }
-/** Used to detect unsigned integer values. */
-var reIsUint = /^(?:0|[1-9]\d*)$/;
+ function _range(count) {
+ return _map(Array(count), function (v, i) { return i; });
+ }
-/**
- * Checks if `value` is a valid array-like index.
- *
- * @private
- * @param {*} value The value to check.
- * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
- * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
- */
-function isIndex(value, length) {
- length = length == null ? MAX_SAFE_INTEGER$1 : length;
- return !!length &&
- (typeof value == 'number' || reIsUint.test(value)) &&
- (value > -1 && value % 1 == 0 && value < length);
-}
-
-/** `Object#toString` result references. */
-var argsTag$1 = '[object Arguments]';
-var arrayTag = '[object Array]';
-var boolTag = '[object Boolean]';
-var dateTag = '[object Date]';
-var errorTag = '[object Error]';
-var funcTag$1 = '[object Function]';
-var mapTag = '[object Map]';
-var numberTag = '[object Number]';
-var objectTag = '[object Object]';
-var regexpTag = '[object RegExp]';
-var setTag = '[object Set]';
-var stringTag = '[object String]';
-var weakMapTag = '[object WeakMap]';
-
-var arrayBufferTag = '[object ArrayBuffer]';
-var dataViewTag = '[object DataView]';
-var float32Tag = '[object Float32Array]';
-var float64Tag = '[object Float64Array]';
-var int8Tag = '[object Int8Array]';
-var int16Tag = '[object Int16Array]';
-var int32Tag = '[object Int32Array]';
-var uint8Tag = '[object Uint8Array]';
-var uint8ClampedTag = '[object Uint8ClampedArray]';
-var uint16Tag = '[object Uint16Array]';
-var uint32Tag = '[object Uint32Array]';
-
-/** Used to identify `toStringTag` values of typed arrays. */
-var typedArrayTags = {};
-typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
-typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
-typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
-typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
-typedArrayTags[uint32Tag] = true;
-typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
-typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
-typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
-typedArrayTags[errorTag] = typedArrayTags[funcTag$1] =
-typedArrayTags[mapTag] = typedArrayTags[numberTag] =
-typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
-typedArrayTags[setTag] = typedArrayTags[stringTag] =
-typedArrayTags[weakMapTag] = false;
-
-/**
- * The base implementation of `_.isTypedArray` without Node.js optimizations.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
- */
-function baseIsTypedArray(value) {
- return isObjectLike(value) &&
- isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
-}
+ function _reduce(arr, iterator, memo) {
+ _arrayEach(arr, function (x, i, a) {
+ memo = iterator(memo, x, i, a);
+ });
+ return memo;
+ }
-/**
- * The base implementation of `_.unary` without support for storing metadata.
- *
- * @private
- * @param {Function} func The function to cap arguments for.
- * @returns {Function} Returns the new capped function.
- */
-function baseUnary(func) {
- return function(value) {
- return func(value);
- };
-}
+ function _forEachOf(object, iterator) {
+ _arrayEach(_keys(object), function (key) {
+ iterator(object[key], key);
+ });
+ }
-/** Detect free variable `exports`. */
-var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
+ function _indexOf(arr, item) {
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] === item) return i;
+ }
+ return -1;
+ }
-/** Detect free variable `module`. */
-var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
+ var _keys = Object.keys || function (obj) {
+ var keys = [];
+ for (var k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ keys.push(k);
+ }
+ }
+ return keys;
+ };
-/** Detect the popular CommonJS extension `module.exports`. */
-var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
+ function _keyIterator(coll) {
+ var i = -1;
+ var len;
+ var keys;
+ if (_isArrayLike(coll)) {
+ len = coll.length;
+ return function next() {
+ i++;
+ return i < len ? i : null;
+ };
+ } else {
+ keys = _keys(coll);
+ len = keys.length;
+ return function next() {
+ i++;
+ return i < len ? keys[i] : null;
+ };
+ }
+ }
-/** Detect free variable `process` from Node.js. */
-var freeProcess = moduleExports$1 && freeGlobal.process;
+ // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
+ // This accumulates the arguments passed into an array, after a given index.
+ // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).
+ function _restParam(func, startIndex) {
+ startIndex = startIndex == null ? func.length - 1 : +startIndex;
+ return function() {
+ var length = Math.max(arguments.length - startIndex, 0);
+ var rest = Array(length);
+ for (var index = 0; index < length; index++) {
+ rest[index] = arguments[index + startIndex];
+ }
+ switch (startIndex) {
+ case 0: return func.call(this, rest);
+ case 1: return func.call(this, arguments[0], rest);
+ }
+ // Currently unused but handle cases outside of the switch statement:
+ // var args = Array(startIndex + 1);
+ // for (index = 0; index < startIndex; index++) {
+ // args[index] = arguments[index];
+ // }
+ // args[startIndex] = rest;
+ // return func.apply(this, args);
+ };
+ }
-/** Used to access faster Node.js helpers. */
-var nodeUtil = (function() {
- try {
- return freeProcess && freeProcess.binding('util');
- } catch (e) {}
-}());
+ function _withoutIndex(iterator) {
+ return function (value, index, callback) {
+ return iterator(value, callback);
+ };
+ }
-/* Node.js helper references. */
-var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
+ //// exported async module functions ////
-/**
- * Checks if `value` is classified as a typed array.
- *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
- * @example
- *
- * _.isTypedArray(new Uint8Array);
- * // => true
- *
- * _.isTypedArray([]);
- * // => false
- */
-var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
+ //// nextTick implementation with browser-compatible fallback ////
-/** Used for built-in method references. */
-var objectProto$2 = Object.prototype;
+ // capture the global reference to guard against fakeTimer mocks
+ var _setImmediate = typeof setImmediate === 'function' && setImmediate;
-/** Used to check objects for own properties. */
-var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
+ var _delay = _setImmediate ? function(fn) {
+ // not a direct alias for IE10 compatibility
+ _setImmediate(fn);
+ } : function(fn) {
+ setTimeout(fn, 0);
+ };
-/**
- * Creates an array of the enumerable property names of the array-like `value`.
- *
- * @private
- * @param {*} value The value to query.
- * @param {boolean} inherited Specify returning inherited property names.
- * @returns {Array} Returns the array of property names.
- */
-function arrayLikeKeys(value, inherited) {
- var isArr = isArray(value),
- isArg = !isArr && isArguments(value),
- isBuff = !isArr && !isArg && isBuffer(value),
- isType = !isArr && !isArg && !isBuff && isTypedArray(value),
- skipIndexes = isArr || isArg || isBuff || isType,
- result = skipIndexes ? baseTimes(value.length, String) : [],
- length = result.length;
-
- for (var key in value) {
- if ((inherited || hasOwnProperty$1.call(value, key)) &&
- !(skipIndexes && (
- // Safari 9 has enumerable `arguments.length` in strict mode.
- key == 'length' ||
- // Node.js 0.10 has enumerable non-index properties on buffers.
- (isBuff && (key == 'offset' || key == 'parent')) ||
- // PhantomJS 2 has enumerable non-index properties on typed arrays.
- (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
- // Skip index properties.
- isIndex(key, length)
- ))) {
- result.push(key);
+ if (typeof process === 'object' && typeof process.nextTick === 'function') {
+ async.nextTick = process.nextTick;
+ } else {
+ async.nextTick = _delay;
}
- }
- return result;
-}
-
-/** Used for built-in method references. */
-var objectProto$5 = Object.prototype;
-
-/**
- * Checks if `value` is likely a prototype object.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
- */
-function isPrototype(value) {
- var Ctor = value && value.constructor,
- proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5;
-
- return value === proto;
-}
-
-/**
- * Creates a unary function that invokes `func` with its argument transformed.
- *
- * @private
- * @param {Function} func The function to wrap.
- * @param {Function} transform The argument transform.
- * @returns {Function} Returns the new function.
- */
-function overArg(func, transform) {
- return function(arg) {
- return func(transform(arg));
- };
-}
+ async.setImmediate = _setImmediate ? _delay : async.nextTick;
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeKeys = overArg(Object.keys, Object);
-/** Used for built-in method references. */
-var objectProto$4 = Object.prototype;
+ async.forEach =
+ async.each = function (arr, iterator, callback) {
+ return async.eachOf(arr, _withoutIndex(iterator), callback);
+ };
-/** Used to check objects for own properties. */
-var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
+ async.forEachSeries =
+ async.eachSeries = function (arr, iterator, callback) {
+ return async.eachOfSeries(arr, _withoutIndex(iterator), callback);
+ };
-/**
- * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- */
-function baseKeys(object) {
- if (!isPrototype(object)) {
- return nativeKeys(object);
- }
- var result = [];
- for (var key in Object(object)) {
- if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
- result.push(key);
- }
- }
- return result;
-}
-/**
- * Creates an array of the own enumerable property names of `object`.
- *
- * **Note:** Non-object values are coerced to objects. See the
- * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
- * for more details.
- *
- * @static
- * @since 0.1.0
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- * @example
- *
- * function Foo() {
- * this.a = 1;
- * this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.keys(new Foo);
- * // => ['a', 'b'] (iteration order is not guaranteed)
- *
- * _.keys('hi');
- * // => ['0', '1']
- */
-function keys(object) {
- return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
-}
-
-function createArrayIterator(coll) {
- var i = -1;
- var len = coll.length;
- return function next() {
- return ++i < len ? {value: coll[i], key: i} : null;
- }
-}
-
-function createES2015Iterator(iterator) {
- var i = -1;
- return function next() {
- var item = iterator.next();
- if (item.done)
- return null;
- i++;
- return {value: item.value, key: i};
- }
-}
-
-function createObjectIterator(obj) {
- var okeys = keys(obj);
- var i = -1;
- var len = okeys.length;
- return function next() {
- var key = okeys[++i];
- return i < len ? {value: obj[key], key: key} : null;
+ async.forEachLimit =
+ async.eachLimit = function (arr, limit, iterator, callback) {
+ return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);
};
-}
-function iterator(coll) {
- if (isArrayLike(coll)) {
- return createArrayIterator(coll);
- }
+ async.forEachOf =
+ async.eachOf = function (object, iterator, callback) {
+ callback = _once(callback || noop);
+ object = object || [];
- var iterator = getIterator(coll);
- return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
-}
+ var iter = _keyIterator(object);
+ var key, completed = 0;
-function onlyOnce(fn) {
- return function() {
- if (fn === null) throw new Error("Callback was already called.");
- var callFn = fn;
- fn = null;
- callFn.apply(this, arguments);
- };
-}
-
-function _eachOfLimit(limit) {
- return function (obj, iteratee, callback) {
- callback = once(callback || noop);
- if (limit <= 0 || !obj) {
- return callback(null);
+ while ((key = iter()) != null) {
+ completed += 1;
+ iterator(object[key], key, only_once(done));
}
- var nextElem = iterator(obj);
- var done = false;
- var running = 0;
- function iterateeCallback(err, value) {
- running -= 1;
+ if (completed === 0) callback(null);
+
+ function done(err) {
+ completed--;
if (err) {
- done = true;
callback(err);
}
- else if (value === breakLoop || (done && running <= 0)) {
- done = true;
- return callback(null);
- }
- else {
- replenish();
+ // Check key is null in case iterator isn't exhausted
+ // and done resolved synchronously.
+ else if (key === null && completed <= 0) {
+ callback(null);
}
}
+ };
- function replenish () {
- while (running < limit && !done) {
- var elem = nextElem();
- if (elem === null) {
- done = true;
- if (running <= 0) {
- callback(null);
+ async.forEachOfSeries =
+ async.eachOfSeries = function (obj, iterator, callback) {
+ callback = _once(callback || noop);
+ obj = obj || [];
+ var nextKey = _keyIterator(obj);
+ var key = nextKey();
+ function iterate() {
+ var sync = true;
+ if (key === null) {
+ return callback(null);
+ }
+ iterator(obj[key], key, only_once(function (err) {
+ if (err) {
+ callback(err);
+ }
+ else {
+ key = nextKey();
+ if (key === null) {
+ return callback(null);
+ } else {
+ if (sync) {
+ async.setImmediate(iterate);
+ } else {
+ iterate();
+ }
}
- return;
}
- running += 1;
- iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
- }
+ }));
+ sync = false;
}
-
- replenish();
+ iterate();
};
-}
-/**
- * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name eachOfLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.eachOf]{@link module:Collections.eachOf}
- * @alias forEachOfLimit
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async function to apply to each
- * item in `coll`. The `key` is the item's key, or index in the case of an
- * array.
- * Invoked with (item, key, callback).
- * @param {Function} [callback] - A callback which is called when all
- * `iteratee` functions have finished, or an error occurs. Invoked with (err).
- */
-function eachOfLimit(coll, limit, iteratee, callback) {
- _eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
-}
-function doLimit(fn, limit) {
- return function (iterable, iteratee, callback) {
- return fn(iterable, limit, iteratee, callback);
- };
-}
-
-// eachOf implementation optimized for array-likes
-function eachOfArrayLike(coll, iteratee, callback) {
- callback = once(callback || noop);
- var index = 0,
- completed = 0,
- length = coll.length;
- if (length === 0) {
- callback(null);
- }
- function iteratorCallback(err, value) {
- if (err) {
- callback(err);
- } else if ((++completed === length) || value === breakLoop) {
- callback(null);
- }
- }
-
- for (; index < length; index++) {
- iteratee(coll[index], index, onlyOnce(iteratorCallback));
- }
-}
-
-// a generic version of eachOf which can handle array, object, and iterator cases.
-var eachOfGeneric = doLimit(eachOfLimit, Infinity);
-
-/**
- * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
- * to the iteratee.
- *
- * @name eachOf
- * @static
- * @memberOf module:Collections
- * @method
- * @alias forEachOf
- * @category Collection
- * @see [async.each]{@link module:Collections.each}
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A function to apply to each
- * item in `coll`.
- * The `key` is the item's key, or index in the case of an array.
- * Invoked with (item, key, callback).
- * @param {Function} [callback] - A callback which is called when all
- * `iteratee` functions have finished, or an error occurs. Invoked with (err).
- * @example
- *
- * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
- * var configs = {};
- *
- * async.forEachOf(obj, function (value, key, callback) {
- * fs.readFile(__dirname + value, "utf8", function (err, data) {
- * if (err) return callback(err);
- * try {
- * configs[key] = JSON.parse(data);
- * } catch (e) {
- * return callback(e);
- * }
- * callback();
- * });
- * }, function (err) {
- * if (err) console.error(err.message);
- * // configs is now a map of JSON data
- * doSomethingWith(configs);
- * });
- */
-var eachOf = function(coll, iteratee, callback) {
- var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
- eachOfImplementation(coll, wrapAsync(iteratee), callback);
-};
-
-function doParallel(fn) {
- return function (obj, iteratee, callback) {
- return fn(eachOf, obj, wrapAsync(iteratee), callback);
- };
-}
-
-function _asyncMap(eachfn, arr, iteratee, callback) {
- callback = callback || noop;
- arr = arr || [];
- var results = [];
- var counter = 0;
- var _iteratee = wrapAsync(iteratee);
-
- eachfn(arr, function (value, _, callback) {
- var index = counter++;
- _iteratee(value, function (err, v) {
- results[index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
-}
-
-/**
- * Produces a new collection of values by mapping each value in `coll` through
- * the `iteratee` function. The `iteratee` is called with an item from `coll`
- * and a callback for when it has finished processing. Each of these callback
- * takes 2 arguments: an `error`, and the transformed item from `coll`. If
- * `iteratee` passes an error to its callback, the main `callback` (for the
- * `map` function) is immediately called with the error.
- *
- * Note, that since this function applies the `iteratee` to each item in
- * parallel, there is no guarantee that the `iteratee` functions will complete
- * in order. However, the results array will be in the same order as the
- * original `coll`.
- *
- * If `map` is passed an Object, the results will be an Array. The results
- * will roughly be in the order of the original Objects' keys (but this can
- * vary across JavaScript engines).
- *
- * @name map
- * @static
- * @memberOf module:Collections
- * @method
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with the transformed item.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Results is an Array of the
- * transformed items from the `coll`. Invoked with (err, results).
- * @example
- *
- * async.map(['file1','file2','file3'], fs.stat, function(err, results) {
- * // results is now an array of stats for each file
- * });
- */
-var map = doParallel(_asyncMap);
-
-/**
- * Applies the provided arguments to each function in the array, calling
- * `callback` after all functions have completed. If you only provide the first
- * argument, `fns`, then it will return a function which lets you pass in the
- * arguments as if it were a single function call. If more arguments are
- * provided, `callback` is required while `args` is still optional.
- *
- * @name applyEach
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s
- * to all call with the same arguments
- * @param {...*} [args] - any number of separate arguments to pass to the
- * function.
- * @param {Function} [callback] - the final argument should be the callback,
- * called when all functions have completed processing.
- * @returns {Function} - If only the first argument, `fns`, is provided, it will
- * return a function which lets you pass in the arguments as if it were a single
- * function call. The signature is `(..args, callback)`. If invoked with any
- * arguments, `callback` is required.
- * @example
- *
- * async.applyEach([enableSearch, updateSchema], 'bucket', callback);
- *
- * // partial application example:
- * async.each(
- * buckets,
- * async.applyEach([enableSearch, updateSchema]),
- * callback
- * );
- */
-var applyEach = applyEach$1(map);
-
-function doParallelLimit(fn) {
- return function (obj, limit, iteratee, callback) {
- return fn(_eachOfLimit(limit), obj, wrapAsync(iteratee), callback);
- };
-}
-
-/**
- * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
- *
- * @name mapLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.map]{@link module:Collections.map}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with the transformed item.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Results is an array of the
- * transformed items from the `coll`. Invoked with (err, results).
- */
-var mapLimit = doParallelLimit(_asyncMap);
-
-/**
- * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
- *
- * @name mapSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.map]{@link module:Collections.map}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with the transformed item.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Results is an array of the
- * transformed items from the `coll`. Invoked with (err, results).
- */
-var mapSeries = doLimit(mapLimit, 1);
-
-/**
- * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
- *
- * @name applyEachSeries
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.applyEach]{@link module:ControlFlow.applyEach}
- * @category Control Flow
- * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s to all
- * call with the same arguments
- * @param {...*} [args] - any number of separate arguments to pass to the
- * function.
- * @param {Function} [callback] - the final argument should be the callback,
- * called when all functions have completed processing.
- * @returns {Function} - If only the first argument is provided, it will return
- * a function which lets you pass in the arguments as if it were a single
- * function call.
- */
-var applyEachSeries = applyEach$1(mapSeries);
-
-/**
- * Creates a continuation function with some arguments already applied.
- *
- * Useful as a shorthand when combined with other control flow functions. Any
- * arguments passed to the returned function are added to the arguments
- * originally passed to apply.
- *
- * @name apply
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {Function} fn - The function you want to eventually apply all
- * arguments to. Invokes with (arguments...).
- * @param {...*} arguments... - Any number of arguments to automatically apply
- * when the continuation is called.
- * @returns {Function} the partially-applied function
- * @example
- *
- * // using apply
- * async.parallel([
- * async.apply(fs.writeFile, 'testfile1', 'test1'),
- * async.apply(fs.writeFile, 'testfile2', 'test2')
- * ]);
- *
- *
- * // the same process without using apply
- * async.parallel([
- * function(callback) {
- * fs.writeFile('testfile1', 'test1', callback);
- * },
- * function(callback) {
- * fs.writeFile('testfile2', 'test2', callback);
- * }
- * ]);
- *
- * // It's possible to pass any number of additional arguments when calling the
- * // continuation:
- *
- * node> var fn = async.apply(sys.puts, 'one');
- * node> fn('two', 'three');
- * one
- * two
- * three
- */
-var apply = function(fn/*, ...args*/) {
- var args = slice(arguments, 1);
- return function(/*callArgs*/) {
- var callArgs = slice(arguments);
- return fn.apply(null, args.concat(callArgs));
+ async.forEachOfLimit =
+ async.eachOfLimit = function (obj, limit, iterator, callback) {
+ _eachOfLimit(limit)(obj, iterator, callback);
};
-};
-/**
- * A specialized version of `_.forEach` for arrays without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns `array`.
- */
-function arrayEach(array, iteratee) {
- var index = -1,
- length = array == null ? 0 : array.length;
-
- while (++index < length) {
- if (iteratee(array[index], index, array) === false) {
- break;
- }
- }
- return array;
-}
+ function _eachOfLimit(limit) {
-/**
- * Creates a base function for methods like `_.forIn` and `_.forOwn`.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
-function createBaseFor(fromRight) {
- return function(object, iteratee, keysFunc) {
- var index = -1,
- iterable = Object(object),
- props = keysFunc(object),
- length = props.length;
-
- while (length--) {
- var key = props[fromRight ? length : ++index];
- if (iteratee(iterable[key], key, iterable) === false) {
- break;
- }
- }
- return object;
- };
-}
-
-/**
- * The base implementation of `baseForOwn` which iterates over `object`
- * properties returned by `keysFunc` and invokes `iteratee` for each property.
- * Iteratee functions may exit iteration early by explicitly returning `false`.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} keysFunc The function to get the keys of `object`.
- * @returns {Object} Returns `object`.
- */
-var baseFor = createBaseFor();
-
-/**
- * The base implementation of `_.forOwn` without support for iteratee shorthands.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Object} Returns `object`.
- */
-function baseForOwn(object, iteratee) {
- return object && baseFor(object, iteratee, keys);
-}
+ return function (obj, iterator, callback) {
+ callback = _once(callback || noop);
+ obj = obj || [];
+ var nextKey = _keyIterator(obj);
+ if (limit <= 0) {
+ return callback(null);
+ }
+ var done = false;
+ var running = 0;
+ var errored = false;
-/**
- * The base implementation of `_.findIndex` and `_.findLastIndex` without
- * support for iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Function} predicate The function invoked per iteration.
- * @param {number} fromIndex The index to search from.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
-function baseFindIndex(array, predicate, fromIndex, fromRight) {
- var length = array.length,
- index = fromIndex + (fromRight ? 1 : -1);
+ (function replenish () {
+ if (done && running <= 0) {
+ return callback(null);
+ }
- while ((fromRight ? index-- : ++index < length)) {
- if (predicate(array[index], index, array)) {
- return index;
+ while (running < limit && !errored) {
+ var key = nextKey();
+ if (key === null) {
+ done = true;
+ if (running <= 0) {
+ callback(null);
+ }
+ return;
+ }
+ running += 1;
+ iterator(obj[key], key, only_once(function (err) {
+ running -= 1;
+ if (err) {
+ callback(err);
+ errored = true;
+ }
+ else {
+ replenish();
+ }
+ }));
+ }
+ })();
+ };
}
- }
- return -1;
-}
-
-/**
- * The base implementation of `_.isNaN` without support for number objects.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
- */
-function baseIsNaN(value) {
- return value !== value;
-}
-
-/**
- * A specialized version of `_.indexOf` which performs strict equality
- * comparisons of values, i.e. `===`.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
-function strictIndexOf(array, value, fromIndex) {
- var index = fromIndex - 1,
- length = array.length;
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
-}
-/**
- * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
-function baseIndexOf(array, value, fromIndex) {
- return value === value
- ? strictIndexOf(array, value, fromIndex)
- : baseFindIndex(array, baseIsNaN, fromIndex);
-}
-
-/**
- * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
- * their requirements. Each function can optionally depend on other functions
- * being completed first, and each function is run as soon as its requirements
- * are satisfied.
- *
- * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
- * will stop. Further tasks will not execute (so any other functions depending
- * on it will not run), and the main `callback` is immediately called with the
- * error.
- *
- * {@link AsyncFunction}s also receive an object containing the results of functions which
- * have completed so far as the first argument, if they have dependencies. If a
- * task function has no dependencies, it will only be passed a callback.
- *
- * @name auto
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Object} tasks - An object. Each of its properties is either a
- * function or an array of requirements, with the {@link AsyncFunction} itself the last item
- * in the array. The object's key of a property serves as the name of the task
- * defined by that property, i.e. can be used when specifying requirements for
- * other tasks. The function receives one or two arguments:
- * * a `results` object, containing the results of the previously executed
- * functions, only passed if the task has any dependencies,
- * * a `callback(err, result)` function, which must be called when finished,
- * passing an `error` (which can be `null`) and the result of the function's
- * execution.
- * @param {number} [concurrency=Infinity] - An optional `integer` for
- * determining the maximum number of tasks that can be run in parallel. By
- * default, as many as possible.
- * @param {Function} [callback] - An optional callback which is called when all
- * the tasks have been completed. It receives the `err` argument if any `tasks`
- * pass an error to their callback. Results are always returned; however, if an
- * error occurs, no further `tasks` will be performed, and the results object
- * will only contain partial results. Invoked with (err, results).
- * @returns undefined
- * @example
- *
- * async.auto({
- * // this function will just be passed a callback
- * readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
- * showData: ['readData', function(results, cb) {
- * // results.readData is the file's contents
- * // ...
- * }]
- * }, callback);
- *
- * async.auto({
- * get_data: function(callback) {
- * console.log('in get_data');
- * // async code to get some data
- * callback(null, 'data', 'converted to array');
- * },
- * make_folder: function(callback) {
- * console.log('in make_folder');
- * // async code to create a directory to store a file in
- * // this is run at the same time as getting the data
- * callback(null, 'folder');
- * },
- * write_file: ['get_data', 'make_folder', function(results, callback) {
- * console.log('in write_file', JSON.stringify(results));
- * // once there is some data and the directory exists,
- * // write the data to a file in the directory
- * callback(null, 'filename');
- * }],
- * email_link: ['write_file', function(results, callback) {
- * console.log('in email_link', JSON.stringify(results));
- * // once the file is written let's email a link to it...
- * // results.write_file contains the filename returned by write_file.
- * callback(null, {'file':results.write_file, 'email':'user@example.com'});
- * }]
- * }, function(err, results) {
- * console.log('err = ', err);
- * console.log('results = ', results);
- * });
- */
-var auto = function (tasks, concurrency, callback) {
- if (typeof concurrency === 'function') {
- // concurrency is optional, shift the args.
- callback = concurrency;
- concurrency = null;
+ function doParallel(fn) {
+ return function (obj, iterator, callback) {
+ return fn(async.eachOf, obj, iterator, callback);
+ };
}
- callback = once(callback || noop);
- var keys$$1 = keys(tasks);
- var numTasks = keys$$1.length;
- if (!numTasks) {
- return callback(null);
+ function doParallelLimit(fn) {
+ return function (obj, limit, iterator, callback) {
+ return fn(_eachOfLimit(limit), obj, iterator, callback);
+ };
}
- if (!concurrency) {
- concurrency = numTasks;
+ function doSeries(fn) {
+ return function (obj, iterator, callback) {
+ return fn(async.eachOfSeries, obj, iterator, callback);
+ };
}
- var results = {};
- var runningTasks = 0;
- var hasError = false;
-
- var listeners = Object.create(null);
-
- var readyTasks = [];
-
- // for cycle detection:
- var readyToCheck = []; // tasks that have been identified as reachable
- // without the possibility of returning to an ancestor task
- var uncheckedDependencies = {};
-
- baseForOwn(tasks, function (task, key) {
- if (!isArray(task)) {
- // no dependencies
- enqueueTask(key, [task]);
- readyToCheck.push(key);
- return;
- }
-
- var dependencies = task.slice(0, task.length - 1);
- var remainingDependencies = dependencies.length;
- if (remainingDependencies === 0) {
- enqueueTask(key, task);
- readyToCheck.push(key);
- return;
- }
- uncheckedDependencies[key] = remainingDependencies;
-
- arrayEach(dependencies, function (dependencyName) {
- if (!tasks[dependencyName]) {
- throw new Error('async.auto task `' + key +
- '` has a non-existent dependency `' +
- dependencyName + '` in ' +
- dependencies.join(', '));
- }
- addListener(dependencyName, function () {
- remainingDependencies--;
- if (remainingDependencies === 0) {
- enqueueTask(key, task);
- }
+ function _asyncMap(eachfn, arr, iterator, callback) {
+ callback = _once(callback || noop);
+ arr = arr || [];
+ var results = _isArrayLike(arr) ? [] : {};
+ eachfn(arr, function (value, index, callback) {
+ iterator(value, function (err, v) {
+ results[index] = v;
+ callback(err);
});
- });
- });
-
- checkForDeadlocks();
- processQueue();
-
- function enqueueTask(key, task) {
- readyTasks.push(function () {
- runTask(key, task);
+ }, function (err) {
+ callback(err, results);
});
}
- function processQueue() {
- if (readyTasks.length === 0 && runningTasks === 0) {
- return callback(null, results);
- }
- while(readyTasks.length && runningTasks < concurrency) {
- var run = readyTasks.shift();
- run();
- }
+ async.map = doParallel(_asyncMap);
+ async.mapSeries = doSeries(_asyncMap);
+ async.mapLimit = doParallelLimit(_asyncMap);
+
+ // reduce only has a series version, as doing reduce in parallel won't
+ // work in many situations.
+ async.inject =
+ async.foldl =
+ async.reduce = function (arr, memo, iterator, callback) {
+ async.eachOfSeries(arr, function (x, i, callback) {
+ iterator(memo, x, function (err, v) {
+ memo = v;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, memo);
+ });
+ };
- }
+ async.foldr =
+ async.reduceRight = function (arr, memo, iterator, callback) {
+ var reversed = _map(arr, identity).reverse();
+ async.reduce(reversed, memo, iterator, callback);
+ };
- function addListener(taskName, fn) {
- var taskListeners = listeners[taskName];
- if (!taskListeners) {
- taskListeners = listeners[taskName] = [];
+ async.transform = function (arr, memo, iterator, callback) {
+ if (arguments.length === 3) {
+ callback = iterator;
+ iterator = memo;
+ memo = _isArray(arr) ? [] : {};
}
- taskListeners.push(fn);
- }
+ async.eachOf(arr, function(v, k, cb) {
+ iterator(memo, v, k, cb);
+ }, function(err) {
+ callback(err, memo);
+ });
+ };
- function taskComplete(taskName) {
- var taskListeners = listeners[taskName] || [];
- arrayEach(taskListeners, function (fn) {
- fn();
+ function _filter(eachfn, arr, iterator, callback) {
+ var results = [];
+ eachfn(arr, function (x, index, callback) {
+ iterator(x, function (v) {
+ if (v) {
+ results.push({index: index, value: x});
+ }
+ callback();
+ });
+ }, function () {
+ callback(_map(results.sort(function (a, b) {
+ return a.index - b.index;
+ }), function (x) {
+ return x.value;
+ }));
});
- processQueue();
}
+ async.select =
+ async.filter = doParallel(_filter);
- function runTask(key, task) {
- if (hasError) return;
-
- var taskCallback = onlyOnce(function(err, result) {
- runningTasks--;
- if (arguments.length > 2) {
- result = slice(arguments, 1);
- }
- if (err) {
- var safeResults = {};
- baseForOwn(results, function(val, rkey) {
- safeResults[rkey] = val;
- });
- safeResults[key] = result;
- hasError = true;
- listeners = Object.create(null);
+ async.selectLimit =
+ async.filterLimit = doParallelLimit(_filter);
- callback(err, safeResults);
- } else {
- results[key] = result;
- taskComplete(key);
- }
- });
+ async.selectSeries =
+ async.filterSeries = doSeries(_filter);
- runningTasks++;
- var taskFn = wrapAsync(task[task.length - 1]);
- if (task.length > 1) {
- taskFn(results, taskCallback);
- } else {
- taskFn(taskCallback);
- }
- }
-
- function checkForDeadlocks() {
- // Kahn's algorithm
- // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
- // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
- var currentTask;
- var counter = 0;
- while (readyToCheck.length) {
- currentTask = readyToCheck.pop();
- counter++;
- arrayEach(getDependents(currentTask), function (dependent) {
- if (--uncheckedDependencies[dependent] === 0) {
- readyToCheck.push(dependent);
- }
+ function _reject(eachfn, arr, iterator, callback) {
+ _filter(eachfn, arr, function(value, cb) {
+ iterator(value, function(v) {
+ cb(!v);
});
- }
-
- if (counter !== numTasks) {
- throw new Error(
- 'async.auto cannot execute tasks due to a recursive dependency'
- );
- }
+ }, callback);
}
-
- function getDependents(taskName) {
- var result = [];
- baseForOwn(tasks, function (task, key) {
- if (isArray(task) && baseIndexOf(task, taskName, 0) >= 0) {
- result.push(key);
+ async.reject = doParallel(_reject);
+ async.rejectLimit = doParallelLimit(_reject);
+ async.rejectSeries = doSeries(_reject);
+
+ function _createTester(eachfn, check, getResult) {
+ return function(arr, limit, iterator, cb) {
+ function done() {
+ if (cb) cb(getResult(false, void 0));
}
- });
- return result;
+ function iteratee(x, _, callback) {
+ if (!cb) return callback();
+ iterator(x, function (v) {
+ if (cb && check(v)) {
+ cb(getResult(true, x));
+ cb = iterator = false;
+ }
+ callback();
+ });
+ }
+ if (arguments.length > 3) {
+ eachfn(arr, limit, iteratee, done);
+ } else {
+ cb = iterator;
+ iterator = limit;
+ eachfn(arr, iteratee, done);
+ }
+ };
}
-};
-
-/**
- * A specialized version of `_.map` for arrays without support for iteratee
- * shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the new mapped array.
- */
-function arrayMap(array, iteratee) {
- var index = -1,
- length = array == null ? 0 : array.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iteratee(array[index], index, array);
- }
- return result;
-}
-
-/** `Object#toString` result references. */
-var symbolTag = '[object Symbol]';
-
-/**
- * Checks if `value` is classified as a `Symbol` primitive or object.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
- * @example
- *
- * _.isSymbol(Symbol.iterator);
- * // => true
- *
- * _.isSymbol('abc');
- * // => false
- */
-function isSymbol(value) {
- return typeof value == 'symbol' ||
- (isObjectLike(value) && baseGetTag(value) == symbolTag);
-}
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0;
+ async.any =
+ async.some = _createTester(async.eachOf, toBool, identity);
-/** Used to convert symbols to primitives and strings. */
-var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined;
-var symbolToString = symbolProto ? symbolProto.toString : undefined;
+ async.someLimit = _createTester(async.eachOfLimit, toBool, identity);
-/**
- * The base implementation of `_.toString` which doesn't convert nullish
- * values to empty strings.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- */
-function baseToString(value) {
- // Exit early for strings to avoid a performance hit in some environments.
- if (typeof value == 'string') {
- return value;
- }
- if (isArray(value)) {
- // Recursively convert values (susceptible to call stack limits).
- return arrayMap(value, baseToString) + '';
- }
- if (isSymbol(value)) {
- return symbolToString ? symbolToString.call(value) : '';
- }
- var result = (value + '');
- return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-}
-
-/**
- * The base implementation of `_.slice` without an iteratee call guard.
- *
- * @private
- * @param {Array} array The array to slice.
- * @param {number} [start=0] The start position.
- * @param {number} [end=array.length] The end position.
- * @returns {Array} Returns the slice of `array`.
- */
-function baseSlice(array, start, end) {
- var index = -1,
- length = array.length;
-
- if (start < 0) {
- start = -start > length ? 0 : (length + start);
- }
- end = end > length ? length : end;
- if (end < 0) {
- end += length;
- }
- length = start > end ? 0 : ((end - start) >>> 0);
- start >>>= 0;
-
- var result = Array(length);
- while (++index < length) {
- result[index] = array[index + start];
- }
- return result;
-}
-
-/**
- * Casts `array` to a slice if it's needed.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {number} start The start position.
- * @param {number} [end=array.length] The end position.
- * @returns {Array} Returns the cast slice.
- */
-function castSlice(array, start, end) {
- var length = array.length;
- end = end === undefined ? length : end;
- return (!start && end >= length) ? array : baseSlice(array, start, end);
-}
-
-/**
- * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
- * that is not found in the character symbols.
- *
- * @private
- * @param {Array} strSymbols The string symbols to inspect.
- * @param {Array} chrSymbols The character symbols to find.
- * @returns {number} Returns the index of the last unmatched string symbol.
- */
-function charsEndIndex(strSymbols, chrSymbols) {
- var index = strSymbols.length;
+ async.all =
+ async.every = _createTester(async.eachOf, notId, notId);
- while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
- return index;
-}
+ async.everyLimit = _createTester(async.eachOfLimit, notId, notId);
-/**
- * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
- * that is not found in the character symbols.
- *
- * @private
- * @param {Array} strSymbols The string symbols to inspect.
- * @param {Array} chrSymbols The character symbols to find.
- * @returns {number} Returns the index of the first unmatched string symbol.
- */
-function charsStartIndex(strSymbols, chrSymbols) {
- var index = -1,
- length = strSymbols.length;
-
- while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
- return index;
-}
-
-/**
- * Converts an ASCII `string` to an array.
- *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the converted array.
- */
-function asciiToArray(string) {
- return string.split('');
-}
-
-/** Used to compose unicode character classes. */
-var rsAstralRange = '\\ud800-\\udfff';
-var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23';
-var rsComboSymbolsRange = '\\u20d0-\\u20f0';
-var rsVarRange = '\\ufe0e\\ufe0f';
-
-/** Used to compose unicode capture groups. */
-var rsZWJ = '\\u200d';
-
-/** 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/). */
-var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
-
-/**
- * Checks if `string` contains Unicode symbols.
- *
- * @private
- * @param {string} string The string to inspect.
- * @returns {boolean} Returns `true` if a symbol is found, else `false`.
- */
-function hasUnicode(string) {
- return reHasUnicode.test(string);
-}
-
-/** Used to compose unicode character classes. */
-var rsAstralRange$1 = '\\ud800-\\udfff';
-var rsComboMarksRange$1 = '\\u0300-\\u036f\\ufe20-\\ufe23';
-var rsComboSymbolsRange$1 = '\\u20d0-\\u20f0';
-var rsVarRange$1 = '\\ufe0e\\ufe0f';
-
-/** Used to compose unicode capture groups. */
-var rsAstral = '[' + rsAstralRange$1 + ']';
-var rsCombo = '[' + rsComboMarksRange$1 + rsComboSymbolsRange$1 + ']';
-var rsFitz = '\\ud83c[\\udffb-\\udfff]';
-var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')';
-var rsNonAstral = '[^' + rsAstralRange$1 + ']';
-var rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}';
-var rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]';
-var rsZWJ$1 = '\\u200d';
-
-/** Used to compose unicode regexes. */
-var reOptMod = rsModifier + '?';
-var rsOptVar = '[' + rsVarRange$1 + ']?';
-var rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*';
-var rsSeq = rsOptVar + reOptMod + rsOptJoin;
-var rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
-
-/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
-var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
-
-/**
- * Converts a Unicode `string` to an array.
- *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the converted array.
- */
-function unicodeToArray(string) {
- return string.match(reUnicode) || [];
-}
-
-/**
- * Converts `string` to an array.
- *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the converted array.
- */
-function stringToArray(string) {
- return hasUnicode(string)
- ? unicodeToArray(string)
- : asciiToArray(string);
-}
-
-/**
- * Converts `value` to a string. An empty string is returned for `null`
- * and `undefined` values. The sign of `-0` is preserved.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {string} Returns the converted string.
- * @example
- *
- * _.toString(null);
- * // => ''
- *
- * _.toString(-0);
- * // => '-0'
- *
- * _.toString([1, 2, 3]);
- * // => '1,2,3'
- */
-function toString(value) {
- return value == null ? '' : baseToString(value);
-}
-
-/** Used to match leading and trailing whitespace. */
-var reTrim = /^\s+|\s+$/g;
+ function _findGetResult(v, x) {
+ return x;
+ }
+ async.detect = _createTester(async.eachOf, identity, _findGetResult);
+ async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);
+ async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);
-/**
- * Removes leading and trailing whitespace or specified characters from `string`.
- *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category String
- * @param {string} [string=''] The string to trim.
- * @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
- * @returns {string} Returns the trimmed string.
- * @example
- *
- * _.trim(' abc ');
- * // => 'abc'
- *
- * _.trim('-_-abc-_-', '_-');
- * // => 'abc'
- *
- * _.map([' foo ', ' bar '], _.trim);
- * // => ['foo', 'bar']
- */
-function trim(string, chars, guard) {
- string = toString(string);
- if (string && (guard || chars === undefined)) {
- return string.replace(reTrim, '');
- }
- if (!string || !(chars = baseToString(chars))) {
- return string;
- }
- var strSymbols = stringToArray(string),
- chrSymbols = stringToArray(chars),
- start = charsStartIndex(strSymbols, chrSymbols),
- end = charsEndIndex(strSymbols, chrSymbols) + 1;
-
- return castSlice(strSymbols, start, end).join('');
-}
-
-var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
-var FN_ARG_SPLIT = /,/;
-var FN_ARG = /(=.+)?(\s*)$/;
-var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
-
-function parseParams(func) {
- func = func.toString().replace(STRIP_COMMENTS, '');
- func = func.match(FN_ARGS)[2].replace(' ', '');
- func = func ? func.split(FN_ARG_SPLIT) : [];
- func = func.map(function (arg){
- return trim(arg.replace(FN_ARG, ''));
- });
- return func;
-}
-
-/**
- * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
- * tasks are specified as parameters to the function, after the usual callback
- * parameter, with the parameter names matching the names of the tasks it
- * depends on. This can provide even more readable task graphs which can be
- * easier to maintain.
- *
- * If a final callback is specified, the task results are similarly injected,
- * specified as named parameters after the initial error parameter.
- *
- * The autoInject function is purely syntactic sugar and its semantics are
- * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
- *
- * @name autoInject
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.auto]{@link module:ControlFlow.auto}
- * @category Control Flow
- * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
- * the form 'func([dependencies...], callback). The object's key of a property
- * serves as the name of the task defined by that property, i.e. can be used
- * when specifying requirements for other tasks.
- * * The `callback` parameter is a `callback(err, result)` which must be called
- * when finished, passing an `error` (which can be `null`) and the result of
- * the function's execution. The remaining parameters name other tasks on
- * which the task is dependent, and the results from those tasks are the
- * arguments of those parameters.
- * @param {Function} [callback] - An optional callback which is called when all
- * the tasks have been completed. It receives the `err` argument if any `tasks`
- * pass an error to their callback, and a `results` object with any completed
- * task results, similar to `auto`.
- * @example
- *
- * // The example from `auto` can be rewritten as follows:
- * async.autoInject({
- * get_data: function(callback) {
- * // async code to get some data
- * callback(null, 'data', 'converted to array');
- * },
- * make_folder: function(callback) {
- * // async code to create a directory to store a file in
- * // this is run at the same time as getting the data
- * callback(null, 'folder');
- * },
- * write_file: function(get_data, make_folder, callback) {
- * // once there is some data and the directory exists,
- * // write the data to a file in the directory
- * callback(null, 'filename');
- * },
- * email_link: function(write_file, callback) {
- * // once the file is written let's email a link to it...
- * // write_file contains the filename returned by write_file.
- * callback(null, {'file':write_file, 'email':'user@example.com'});
- * }
- * }, function(err, results) {
- * console.log('err = ', err);
- * console.log('email_link = ', results.email_link);
- * });
- *
- * // If you are using a JS minifier that mangles parameter names, `autoInject`
- * // will not work with plain functions, since the parameter names will be
- * // collapsed to a single letter identifier. To work around this, you can
- * // explicitly specify the names of the parameters your task function needs
- * // in an array, similar to Angular.js dependency injection.
- *
- * // This still has an advantage over plain `auto`, since the results a task
- * // depends on are still spread into arguments.
- * async.autoInject({
- * //...
- * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
- * callback(null, 'filename');
- * }],
- * email_link: ['write_file', function(write_file, callback) {
- * callback(null, {'file':write_file, 'email':'user@example.com'});
- * }]
- * //...
- * }, function(err, results) {
- * console.log('err = ', err);
- * console.log('email_link = ', results.email_link);
- * });
- */
-function autoInject(tasks, callback) {
- var newTasks = {};
-
- baseForOwn(tasks, function (taskFn, key) {
- var params;
- var fnIsAsync = isAsync(taskFn);
- var hasNoDeps =
- (!fnIsAsync && taskFn.length === 1) ||
- (fnIsAsync && taskFn.length === 0);
-
- if (isArray(taskFn)) {
- params = taskFn.slice(0, -1);
- taskFn = taskFn[taskFn.length - 1];
-
- newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
- } else if (hasNoDeps) {
- // no dependencies, use the function as-is
- newTasks[key] = taskFn;
- } else {
- params = parseParams(taskFn);
- if (taskFn.length === 0 && !fnIsAsync && params.length === 0) {
- throw new Error("autoInject task functions require explicit parameters.");
+ async.sortBy = function (arr, iterator, callback) {
+ async.map(arr, function (x, callback) {
+ iterator(x, function (err, criteria) {
+ if (err) {
+ callback(err);
+ }
+ else {
+ callback(null, {value: x, criteria: criteria});
+ }
+ });
+ }, function (err, results) {
+ if (err) {
+ return callback(err);
+ }
+ else {
+ callback(null, _map(results.sort(comparator), function (x) {
+ return x.value;
+ }));
}
- // remove callback param
- if (!fnIsAsync) params.pop();
+ });
- newTasks[key] = params.concat(newTask);
+ function comparator(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
}
+ };
- function newTask(results, taskCb) {
- var newArgs = arrayMap(params, function (name) {
- return results[name];
- });
- newArgs.push(taskCb);
- wrapAsync(taskFn).apply(null, newArgs);
+ async.auto = function (tasks, concurrency, callback) {
+ if (typeof arguments[1] === 'function') {
+ // concurrency is optional, shift the args.
+ callback = concurrency;
+ concurrency = null;
}
- });
-
- auto(newTasks, callback);
-}
-
-// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
-// used for queues. This implementation assumes that the node provided by the user can be modified
-// to adjust the next and last properties. We implement only the minimal functionality
-// for queue support.
-function DLL() {
- this.head = this.tail = null;
- this.length = 0;
-}
-
-function setInitial(dll, node) {
- dll.length = 1;
- dll.head = dll.tail = node;
-}
-
-DLL.prototype.removeLink = function(node) {
- if (node.prev) node.prev.next = node.next;
- else this.head = node.next;
- if (node.next) node.next.prev = node.prev;
- else this.tail = node.prev;
-
- node.prev = node.next = null;
- this.length -= 1;
- return node;
-};
-
-DLL.prototype.empty = function () {
- while(this.head) this.shift();
- return this;
-};
-
-DLL.prototype.insertAfter = function(node, newNode) {
- newNode.prev = node;
- newNode.next = node.next;
- if (node.next) node.next.prev = newNode;
- else this.tail = newNode;
- node.next = newNode;
- this.length += 1;
-};
-
-DLL.prototype.insertBefore = function(node, newNode) {
- newNode.prev = node.prev;
- newNode.next = node;
- if (node.prev) node.prev.next = newNode;
- else this.head = newNode;
- node.prev = newNode;
- this.length += 1;
-};
-
-DLL.prototype.unshift = function(node) {
- if (this.head) this.insertBefore(this.head, node);
- else setInitial(this, node);
-};
-
-DLL.prototype.push = function(node) {
- if (this.tail) this.insertAfter(this.tail, node);
- else setInitial(this, node);
-};
-
-DLL.prototype.shift = function() {
- return this.head && this.removeLink(this.head);
-};
-
-DLL.prototype.pop = function() {
- return this.tail && this.removeLink(this.tail);
-};
-
-DLL.prototype.toArray = function () {
- var arr = Array(this.length);
- var curr = this.head;
- for(var idx = 0; idx < this.length; idx++) {
- arr[idx] = curr.data;
- curr = curr.next;
- }
- return arr;
-};
-
-DLL.prototype.remove = function (testFn) {
- var curr = this.head;
- while(!!curr) {
- var next = curr.next;
- if (testFn(curr)) {
- this.removeLink(curr);
+ callback = _once(callback || noop);
+ var keys = _keys(tasks);
+ var remainingTasks = keys.length;
+ if (!remainingTasks) {
+ return callback(null);
+ }
+ if (!concurrency) {
+ concurrency = remainingTasks;
}
- curr = next;
- }
- return this;
-};
-function queue(worker, concurrency, payload) {
- if (concurrency == null) {
- concurrency = 1;
- }
- else if(concurrency === 0) {
- throw new Error('Concurrency must not be zero');
- }
+ var results = {};
+ var runningTasks = 0;
- var _worker = wrapAsync(worker);
- var numRunning = 0;
- var workersList = [];
+ var hasError = false;
- function _insert(data, insertAtFront, callback) {
- if (callback != null && typeof callback !== 'function') {
- throw new Error('task callback must be a function');
+ var listeners = [];
+ function addListener(fn) {
+ listeners.unshift(fn);
}
- q.started = true;
- if (!isArray(data)) {
- data = [data];
+ function removeListener(fn) {
+ var idx = _indexOf(listeners, fn);
+ if (idx >= 0) listeners.splice(idx, 1);
}
- if (data.length === 0 && q.idle()) {
- // call drain immediately if there are no tasks
- return setImmediate$1(function() {
- q.drain();
+ function taskComplete() {
+ remainingTasks--;
+ _arrayEach(listeners.slice(0), function (fn) {
+ fn();
});
}
- for (var i = 0, l = data.length; i < l; i++) {
- var item = {
- data: data[i],
- callback: callback || noop
- };
-
- if (insertAtFront) {
- q._tasks.unshift(item);
- } else {
- q._tasks.push(item);
+ addListener(function () {
+ if (!remainingTasks) {
+ callback(null, results);
}
- }
- setImmediate$1(q.process);
- }
-
- function _next(tasks) {
- return function(err){
- numRunning -= 1;
-
- for (var i = 0, l = tasks.length; i < l; i++) {
- var task = tasks[i];
+ });
- var index = baseIndexOf(workersList, task, 0);
- if (index >= 0) {
- workersList.splice(index, 1);
+ _arrayEach(keys, function (k) {
+ if (hasError) return;
+ var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
+ var taskCallback = _restParam(function(err, args) {
+ runningTasks--;
+ if (args.length <= 1) {
+ args = args[0];
}
+ if (err) {
+ var safeResults = {};
+ _forEachOf(results, function(val, rkey) {
+ safeResults[rkey] = val;
+ });
+ safeResults[k] = args;
+ hasError = true;
- task.callback.apply(task, arguments);
-
- if (err != null) {
- q.error(err, task.data);
+ callback(err, safeResults);
+ }
+ else {
+ results[k] = args;
+ async.setImmediate(taskComplete);
+ }
+ });
+ var requires = task.slice(0, task.length - 1);
+ // prevent dead-locks
+ var len = requires.length;
+ var dep;
+ while (len--) {
+ if (!(dep = tasks[requires[len]])) {
+ throw new Error('Has nonexistent dependency in ' + requires.join(', '));
+ }
+ if (_isArray(dep) && _indexOf(dep, k) >= 0) {
+ throw new Error('Has cyclic dependencies');
}
}
-
- if (numRunning <= (q.concurrency - q.buffer) ) {
- q.unsaturated();
+ function ready() {
+ return runningTasks < concurrency && _reduce(requires, function (a, x) {
+ return (a && results.hasOwnProperty(x));
+ }, true) && !results.hasOwnProperty(k);
}
-
- if (q.idle()) {
- q.drain();
+ if (ready()) {
+ runningTasks++;
+ task[task.length - 1](taskCallback, results);
}
- q.process();
- };
- }
-
- var isProcessing = false;
- var q = {
- _tasks: new DLL(),
- concurrency: concurrency,
- payload: payload,
- saturated: noop,
- unsaturated:noop,
- buffer: concurrency / 4,
- empty: noop,
- drain: noop,
- error: noop,
- started: false,
- paused: false,
- push: function (data, callback) {
- _insert(data, false, callback);
- },
- kill: function () {
- q.drain = noop;
- q._tasks.empty();
- },
- unshift: function (data, callback) {
- _insert(data, true, callback);
- },
- remove: function (testFn) {
- q._tasks.remove(testFn);
- },
- process: function () {
- // Avoid trying to start too many processing operations. This can occur
- // when callbacks resolve synchronously (#1267).
- if (isProcessing) {
- return;
+ else {
+ addListener(listener);
}
- isProcessing = true;
- while(!q.paused && numRunning < q.concurrency && q._tasks.length){
- var tasks = [], data = [];
- var l = q._tasks.length;
- if (q.payload) l = Math.min(l, q.payload);
- for (var i = 0; i < l; i++) {
- var node = q._tasks.shift();
- tasks.push(node);
- workersList.push(node);
- data.push(node.data);
- }
-
- numRunning += 1;
-
- if (q._tasks.length === 0) {
- q.empty();
+ function listener() {
+ if (ready()) {
+ runningTasks++;
+ removeListener(listener);
+ task[task.length - 1](taskCallback, results);
}
-
- if (numRunning === q.concurrency) {
- q.saturated();
- }
-
- var cb = onlyOnce(_next(tasks));
- _worker(data, cb);
}
- isProcessing = false;
- },
- length: function () {
- return q._tasks.length;
- },
- running: function () {
- return numRunning;
- },
- workersList: function () {
- return workersList;
- },
- idle: function() {
- return q._tasks.length + numRunning === 0;
- },
- pause: function () {
- q.paused = true;
- },
- resume: function () {
- if (q.paused === false) { return; }
- q.paused = false;
- setImmediate$1(q.process);
- }
+ });
};
- return q;
-}
-
-/**
- * A cargo of tasks for the worker function to complete. Cargo inherits all of
- * the same methods and event callbacks as [`queue`]{@link module:ControlFlow.queue}.
- * @typedef {Object} CargoObject
- * @memberOf module:ControlFlow
- * @property {Function} length - A function returning the number of items
- * waiting to be processed. Invoke like `cargo.length()`.
- * @property {number} payload - An `integer` for determining how many tasks
- * should be process per round. This property can be changed after a `cargo` is
- * created to alter the payload on-the-fly.
- * @property {Function} push - Adds `task` to the `queue`. The callback is
- * called once the `worker` has finished processing the task. Instead of a
- * single task, an array of `tasks` can be submitted. The respective callback is
- * used for every task in the list. Invoke like `cargo.push(task, [callback])`.
- * @property {Function} saturated - A callback that is called when the
- * `queue.length()` hits the concurrency and further tasks will be queued.
- * @property {Function} empty - A callback that is called when the last item
- * from the `queue` is given to a `worker`.
- * @property {Function} drain - A callback that is called when the last item
- * from the `queue` has returned from the `worker`.
- * @property {Function} idle - a function returning false if there are items
- * waiting or being processed, or true if not. Invoke like `cargo.idle()`.
- * @property {Function} pause - a function that pauses the processing of tasks
- * until `resume()` is called. Invoke like `cargo.pause()`.
- * @property {Function} resume - a function that resumes the processing of
- * queued tasks when the queue is paused. Invoke like `cargo.resume()`.
- * @property {Function} kill - a function that removes the `drain` callback and
- * empties remaining tasks from the queue forcing it to go idle. Invoke like `cargo.kill()`.
- */
-/**
- * Creates a `cargo` object with the specified payload. Tasks added to the
- * cargo will be processed altogether (up to the `payload` limit). If the
- * `worker` is in progress, the task is queued until it becomes available. Once
- * the `worker` has completed some tasks, each callback of those tasks is
- * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
- * for how `cargo` and `queue` work.
- *
- * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
- * at a time, cargo passes an array of tasks to a single worker, repeating
- * when the worker is finished.
- *
- * @name cargo
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.queue]{@link module:ControlFlow.queue}
- * @category Control Flow
- * @param {AsyncFunction} worker - An asynchronous function for processing an array
- * of queued tasks. Invoked with `(tasks, callback)`.
- * @param {number} [payload=Infinity] - An optional `integer` for determining
- * how many tasks should be processed per round; if omitted, the default is
- * unlimited.
- * @returns {module:ControlFlow.CargoObject} A cargo object to manage the tasks. Callbacks can
- * attached as certain properties to listen for specific events during the
- * lifecycle of the cargo and inner queue.
- * @example
- *
- * // create a cargo object with payload 2
- * var cargo = async.cargo(function(tasks, callback) {
- * for (var i=0; i<tasks.length; i++) {
- * console.log('hello ' + tasks[i].name);
- * }
- * callback();
- * }, 2);
- *
- * // add some items
- * cargo.push({name: 'foo'}, function(err) {
- * console.log('finished processing foo');
- * });
- * cargo.push({name: 'bar'}, function(err) {
- * console.log('finished processing bar');
- * });
- * cargo.push({name: 'baz'}, function(err) {
- * console.log('finished processing baz');
- * });
- */
-function cargo(worker, payload) {
- return queue(worker, 1, payload);
-}
-/**
- * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
- *
- * @name eachOfSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.eachOf]{@link module:Collections.eachOf}
- * @alias forEachOfSeries
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * Invoked with (item, key, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Invoked with (err).
- */
-var eachOfSeries = doLimit(eachOfLimit, 1);
-/**
- * Reduces `coll` into a single value using an async `iteratee` to return each
- * successive step. `memo` is the initial state of the reduction. This function
- * only operates in series.
- *
- * For performance reasons, it may make sense to split a call to this function
- * into a parallel map, and then use the normal `Array.prototype.reduce` on the
- * results. This function is for situations where each step in the reduction
- * needs to be async; if you can get the data before reducing it, then it's
- * probably a good idea to do so.
- *
- * @name reduce
- * @static
- * @memberOf module:Collections
- * @method
- * @alias inject
- * @alias foldl
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {*} memo - The initial state of the reduction.
- * @param {AsyncFunction} iteratee - A function applied to each item in the
- * array to produce the next step in the reduction.
- * The `iteratee` should complete with the next state of the reduction.
- * If the iteratee complete with an error, the reduction is stopped and the
- * main `callback` is immediately called with the error.
- * Invoked with (memo, item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Result is the reduced value. Invoked with
- * (err, result).
- * @example
- *
- * async.reduce([1,2,3], 0, function(memo, item, callback) {
- * // pointless async:
- * process.nextTick(function() {
- * callback(null, memo + item)
- * });
- * }, function(err, result) {
- * // result is now equal to the last value of memo, which is 6
- * });
- */
-function reduce(coll, memo, iteratee, callback) {
- callback = once(callback || noop);
- var _iteratee = wrapAsync(iteratee);
- eachOfSeries(coll, function(x, i, callback) {
- _iteratee(memo, x, function(err, v) {
- memo = v;
- callback(err);
- });
- }, function(err) {
- callback(err, memo);
- });
-}
+ async.retry = function(times, task, callback) {
+ var DEFAULT_TIMES = 5;
+ var DEFAULT_INTERVAL = 0;
-/**
- * Version of the compose function that is more natural to read. Each function
- * consumes the return value of the previous function. It is the equivalent of
- * [compose]{@link module:ControlFlow.compose} with the arguments reversed.
- *
- * Each function is executed with the `this` binding of the composed function.
- *
- * @name seq
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.compose]{@link module:ControlFlow.compose}
- * @category Control Flow
- * @param {...AsyncFunction} functions - the asynchronous functions to compose
- * @returns {Function} a function that composes the `functions` in order
- * @example
- *
- * // Requires lodash (or underscore), express3 and dresende's orm2.
- * // Part of an app, that fetches cats of the logged user.
- * // This example uses `seq` function to avoid overnesting and error
- * // handling clutter.
- * app.get('/cats', function(request, response) {
- * var User = request.models.User;
- * async.seq(
- * _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data))
- * function(user, fn) {
- * user.getCats(fn); // 'getCats' has signature (callback(err, data))
- * }
- * )(req.session.user_id, function (err, cats) {
- * if (err) {
- * console.error(err);
- * response.json({ status: 'error', message: err.message });
- * } else {
- * response.json({ status: 'ok', message: 'Cats found', data: cats });
- * }
- * });
- * });
- */
-function seq(/*...functions*/) {
- var _functions = arrayMap(arguments, wrapAsync);
- return function(/*...args*/) {
- var args = slice(arguments);
- var that = this;
-
- var cb = args[args.length - 1];
- if (typeof cb == 'function') {
- args.pop();
- } else {
- cb = noop;
- }
+ var attempts = [];
- reduce(_functions, args, function(newargs, fn, cb) {
- fn.apply(that, newargs.concat(function(err/*, ...nextargs*/) {
- var nextargs = slice(arguments, 1);
- cb(err, nextargs);
- }));
- },
- function(err, results) {
- cb.apply(that, [err].concat(results));
- });
- };
-}
-
-/**
- * Creates a function which is a composition of the passed asynchronous
- * functions. Each function consumes the return value of the function that
- * follows. Composing functions `f()`, `g()`, and `h()` would produce the result
- * of `f(g(h()))`, only this version uses callbacks to obtain the return values.
- *
- * Each function is executed with the `this` binding of the composed function.
- *
- * @name compose
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {...AsyncFunction} functions - the asynchronous functions to compose
- * @returns {Function} an asynchronous function that is the composed
- * asynchronous `functions`
- * @example
- *
- * function add1(n, callback) {
- * setTimeout(function () {
- * callback(null, n + 1);
- * }, 10);
- * }
- *
- * function mul3(n, callback) {
- * setTimeout(function () {
- * callback(null, n * 3);
- * }, 10);
- * }
- *
- * var add1mul3 = async.compose(mul3, add1);
- * add1mul3(4, function (err, result) {
- * // result now equals 15
- * });
- */
-var compose = function(/*...args*/) {
- return seq.apply(null, slice(arguments).reverse());
-};
-
-var _concat = Array.prototype.concat;
+ var opts = {
+ times: DEFAULT_TIMES,
+ interval: DEFAULT_INTERVAL
+ };
-/**
- * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
- *
- * @name concatLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.concat]{@link module:Collections.concat}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
- * which should use an array as its result. Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished, or an error occurs. Results is an array
- * containing the concatenated results of the `iteratee` function. Invoked with
- * (err, results).
- */
-var concatLimit = function(coll, limit, iteratee, callback) {
- callback = callback || noop;
- var _iteratee = wrapAsync(iteratee);
- mapLimit(coll, limit, function(val, callback) {
- _iteratee(val, function(err /*, ...args*/) {
- if (err) return callback(err);
- return callback(null, slice(arguments, 1));
- });
- }, function(err, mapResults) {
- var result = [];
- for (var i = 0; i < mapResults.length; i++) {
- if (mapResults[i]) {
- result = _concat.apply(result, mapResults[i]);
+ function parseTimes(acc, t){
+ if(typeof t === 'number'){
+ acc.times = parseInt(t, 10) || DEFAULT_TIMES;
+ } else if(typeof t === 'object'){
+ acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
+ acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
+ } else {
+ throw new Error('Unsupported argument type for \'times\': ' + typeof t);
}
}
- return callback(err, result);
- });
-};
-
-/**
- * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
- * the concatenated list. The `iteratee`s are called in parallel, and the
- * results are concatenated as they return. There is no guarantee that the
- * results array will be returned in the original order of `coll` passed to the
- * `iteratee` function.
- *
- * @name concat
- * @static
- * @memberOf module:Collections
- * @method
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
- * which should use an array as its result. Invoked with (item, callback).
- * @param {Function} [callback(err)] - A callback which is called after all the
- * `iteratee` functions have finished, or an error occurs. Results is an array
- * containing the concatenated results of the `iteratee` function. Invoked with
- * (err, results).
- * @example
- *
- * async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) {
- * // files is now a list of filenames that exist in the 3 directories
- * });
- */
-var concat = doLimit(concatLimit, Infinity);
+ var length = arguments.length;
+ if (length < 1 || length > 3) {
+ throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
+ } else if (length <= 2 && typeof times === 'function') {
+ callback = task;
+ task = times;
+ }
+ if (typeof times !== 'function') {
+ parseTimes(opts, times);
+ }
+ opts.callback = callback;
+ opts.task = task;
+
+ function wrappedTask(wrappedCallback, wrappedResults) {
+ function retryAttempt(task, finalAttempt) {
+ return function(seriesCallback) {
+ task(function(err, result){
+ seriesCallback(!err || finalAttempt, {err: err, result: result});
+ }, wrappedResults);
+ };
+ }
-/**
- * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
- *
- * @name concatSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.concat]{@link module:Collections.concat}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
- * The iteratee should complete with an array an array of results.
- * Invoked with (item, callback).
- * @param {Function} [callback(err)] - A callback which is called after all the
- * `iteratee` functions have finished, or an error occurs. Results is an array
- * containing the concatenated results of the `iteratee` function. Invoked with
- * (err, results).
- */
-var concatSeries = doLimit(concatLimit, 1);
+ function retryInterval(interval){
+ return function(seriesCallback){
+ setTimeout(function(){
+ seriesCallback(null);
+ }, interval);
+ };
+ }
-/**
- * Returns a function that when called, calls-back with the values provided.
- * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
- * [`auto`]{@link module:ControlFlow.auto}.
- *
- * @name constant
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {...*} arguments... - Any number of arguments to automatically invoke
- * callback with.
- * @returns {AsyncFunction} Returns a function that when invoked, automatically
- * invokes the callback with the previous given arguments.
- * @example
- *
- * async.waterfall([
- * async.constant(42),
- * function (value, next) {
- * // value === 42
- * },
- * //...
- * ], callback);
- *
- * async.waterfall([
- * async.constant(filename, "utf8"),
- * fs.readFile,
- * function (fileData, next) {
- * //...
- * }
- * //...
- * ], callback);
- *
- * async.auto({
- * hostname: async.constant("https://server.net/"),
- * port: findFreePort,
- * launchServer: ["hostname", "port", function (options, cb) {
- * startServer(options, cb);
- * }],
- * //...
- * }, callback);
- */
-var constant = function(/*...values*/) {
- var values = slice(arguments);
- var args = [null].concat(values);
- return function (/*...ignoredArgs, callback*/) {
- var callback = arguments[arguments.length - 1];
- return callback.apply(this, args);
- };
-};
+ while (opts.times) {
-/**
- * This method returns the first argument it receives.
- *
- * @static
- * @since 0.1.0
- * @memberOf _
- * @category Util
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'a': 1 };
- *
- * console.log(_.identity(object) === object);
- * // => true
- */
-function identity(value) {
- return value;
-}
-
-function _createTester(check, getResult) {
- return function(eachfn, arr, iteratee, cb) {
- cb = cb || noop;
- var testPassed = false;
- var testResult;
- eachfn(arr, function(value, _, callback) {
- iteratee(value, function(err, result) {
- if (err) {
- callback(err);
- } else if (check(result) && !testResult) {
- testPassed = true;
- testResult = getResult(true, value);
- callback(null, breakLoop);
- } else {
- callback();
+ var finalAttempt = !(opts.times-=1);
+ attempts.push(retryAttempt(opts.task, finalAttempt));
+ if(!finalAttempt && opts.interval > 0){
+ attempts.push(retryInterval(opts.interval));
}
- });
- }, function(err) {
- if (err) {
- cb(err);
- } else {
- cb(null, testPassed ? testResult : getResult(false));
}
- });
- };
-}
-function _findGetResult(v, x) {
- return x;
-}
-
-/**
- * Returns the first value in `coll` that passes an async truth test. The
- * `iteratee` is applied in parallel, meaning the first iteratee to return
- * `true` will fire the detect `callback` with that result. That means the
- * result might not be the first item in the original `coll` (in terms of order)
- * that passes the test.
-
- * If order within the original `coll` is important, then look at
- * [`detectSeries`]{@link module:Collections.detectSeries}.
- *
- * @name detect
- * @static
- * @memberOf module:Collections
- * @method
- * @alias find
- * @category Collections
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
- * The iteratee must complete with a boolean value as its result.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called as soon as any
- * iteratee returns `true`, or after all the `iteratee` functions have finished.
- * Result will be the first item in the array that passes the truth test
- * (iteratee) or the value `undefined` if none passed. Invoked with
- * (err, result).
- * @example
- *
- * async.detect(['file1','file2','file3'], function(filePath, callback) {
- * fs.access(filePath, function(err) {
- * callback(null, !err)
- * });
- * }, function(err, result) {
- * // result now equals the first file in the list that exists
- * });
- */
-var detect = doParallel(_createTester(identity, _findGetResult));
+ async.series(attempts, function(done, data){
+ data = data[data.length - 1];
+ (wrappedCallback || opts.callback)(data.err, data.result);
+ });
+ }
-/**
- * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name detectLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.detect]{@link module:Collections.detect}
- * @alias findLimit
- * @category Collections
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
- * The iteratee must complete with a boolean value as its result.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called as soon as any
- * iteratee returns `true`, or after all the `iteratee` functions have finished.
- * Result will be the first item in the array that passes the truth test
- * (iteratee) or the value `undefined` if none passed. Invoked with
- * (err, result).
- */
-var detectLimit = doParallelLimit(_createTester(identity, _findGetResult));
+ // If a callback is passed, run this as a controll flow
+ return opts.callback ? wrappedTask() : wrappedTask;
+ };
-/**
- * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
- *
- * @name detectSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.detect]{@link module:Collections.detect}
- * @alias findSeries
- * @category Collections
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
- * The iteratee must complete with a boolean value as its result.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called as soon as any
- * iteratee returns `true`, or after all the `iteratee` functions have finished.
- * Result will be the first item in the array that passes the truth test
- * (iteratee) or the value `undefined` if none passed. Invoked with
- * (err, result).
- */
-var detectSeries = doLimit(detectLimit, 1);
-
-function consoleFunc(name) {
- return function (fn/*, ...args*/) {
- var args = slice(arguments, 1);
- args.push(function (err/*, ...args*/) {
- var args = slice(arguments, 1);
- if (typeof console === 'object') {
+ async.waterfall = function (tasks, callback) {
+ callback = _once(callback || noop);
+ if (!_isArray(tasks)) {
+ var err = new Error('First argument to waterfall must be an array of functions');
+ return callback(err);
+ }
+ if (!tasks.length) {
+ return callback();
+ }
+ function wrapIterator(iterator) {
+ return _restParam(function (err, args) {
if (err) {
- if (console.error) {
- console.error(err);
+ callback.apply(null, [err].concat(args));
+ }
+ else {
+ var next = iterator.next();
+ if (next) {
+ args.push(wrapIterator(next));
}
- } else if (console[name]) {
- arrayEach(args, function (x) {
- console[name](x);
- });
+ else {
+ args.push(callback);
+ }
+ ensureAsync(iterator).apply(null, args);
}
- }
- });
- wrapAsync(fn).apply(null, args);
+ });
+ }
+ wrapIterator(async.iterator(tasks))();
};
-}
-
-/**
- * Logs the result of an [`async` function]{@link AsyncFunction} to the
- * `console` using `console.dir` to display the properties of the resulting object.
- * Only works in Node.js or in browsers that support `console.dir` and
- * `console.error` (such as FF and Chrome).
- * If multiple arguments are returned from the async function,
- * `console.dir` is called on each argument in order.
- *
- * @name dir
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {AsyncFunction} function - The function you want to eventually apply
- * all arguments to.
- * @param {...*} arguments... - Any number of arguments to apply to the function.
- * @example
- *
- * // in a module
- * var hello = function(name, callback) {
- * setTimeout(function() {
- * callback(null, {hello: name});
- * }, 1000);
- * };
- *
- * // in the node repl
- * node> async.dir(hello, 'world');
- * {hello: 'world'}
- */
-var dir = consoleFunc('dir');
-/**
- * The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in
- * the order of operations, the arguments `test` and `fn` are switched.
- *
- * Also a version of [`doWhilst`]{@link module:ControlFlow.doWhilst} with asynchronous `test` function.
- * @name doDuring
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.during]{@link module:ControlFlow.during}
- * @category Control Flow
- * @param {AsyncFunction} fn - An async function which is called each time
- * `test` passes. Invoked with (callback).
- * @param {AsyncFunction} test - asynchronous truth test to perform before each
- * execution of `fn`. Invoked with (...args, callback), where `...args` are the
- * non-error args from the previous callback of `fn`.
- * @param {Function} [callback] - A callback which is called after the test
- * function has failed and repeated execution of `fn` has stopped. `callback`
- * will be passed an error if one occurred, otherwise `null`.
- */
-function doDuring(fn, test, callback) {
- callback = onlyOnce(callback || noop);
- var _fn = wrapAsync(fn);
- var _test = wrapAsync(test);
-
- function next(err/*, ...args*/) {
- if (err) return callback(err);
- var args = slice(arguments, 1);
- args.push(check);
- _test.apply(this, args);
- }
+ function _parallel(eachfn, tasks, callback) {
+ callback = callback || noop;
+ var results = _isArrayLike(tasks) ? [] : {};
- function check(err, truth) {
- if (err) return callback(err);
- if (!truth) return callback(null);
- _fn(next);
+ eachfn(tasks, function (task, key, callback) {
+ task(_restParam(function (err, args) {
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ results[key] = args;
+ callback(err);
+ }));
+ }, function (err) {
+ callback(err, results);
+ });
}
- check(null, true);
-
-}
-
-/**
- * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
- * the order of operations, the arguments `test` and `iteratee` are switched.
- *
- * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
- *
- * @name doWhilst
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.whilst]{@link module:ControlFlow.whilst}
- * @category Control Flow
- * @param {AsyncFunction} iteratee - A function which is called each time `test`
- * passes. Invoked with (callback).
- * @param {Function} test - synchronous truth test to perform after each
- * execution of `iteratee`. Invoked with any non-error callback results of
- * `iteratee`.
- * @param {Function} [callback] - A callback which is called after the test
- * function has failed and repeated execution of `iteratee` has stopped.
- * `callback` will be passed an error and any arguments passed to the final
- * `iteratee`'s callback. Invoked with (err, [results]);
- */
-function doWhilst(iteratee, test, callback) {
- callback = onlyOnce(callback || noop);
- var _iteratee = wrapAsync(iteratee);
- var next = function(err/*, ...args*/) {
- if (err) return callback(err);
- var args = slice(arguments, 1);
- if (test.apply(this, args)) return _iteratee(next);
- callback.apply(null, [null].concat(args));
+ async.parallel = function (tasks, callback) {
+ _parallel(async.eachOf, tasks, callback);
};
- _iteratee(next);
-}
-
-/**
- * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
- * argument ordering differs from `until`.
- *
- * @name doUntil
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
- * @category Control Flow
- * @param {AsyncFunction} iteratee - An async function which is called each time
- * `test` fails. Invoked with (callback).
- * @param {Function} test - synchronous truth test to perform after each
- * execution of `iteratee`. Invoked with any non-error callback results of
- * `iteratee`.
- * @param {Function} [callback] - A callback which is called after the test
- * function has passed and repeated execution of `iteratee` has stopped. `callback`
- * will be passed an error and any arguments passed to the final `iteratee`'s
- * callback. Invoked with (err, [results]);
- */
-function doUntil(iteratee, test, callback) {
- doWhilst(iteratee, function() {
- return !test.apply(this, arguments);
- }, callback);
-}
-
-/**
- * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that
- * is passed a callback in the form of `function (err, truth)`. If error is
- * passed to `test` or `fn`, the main callback is immediately called with the
- * value of the error.
- *
- * @name during
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.whilst]{@link module:ControlFlow.whilst}
- * @category Control Flow
- * @param {AsyncFunction} test - asynchronous truth test to perform before each
- * execution of `fn`. Invoked with (callback).
- * @param {AsyncFunction} fn - An async function which is called each time
- * `test` passes. Invoked with (callback).
- * @param {Function} [callback] - A callback which is called after the test
- * function has failed and repeated execution of `fn` has stopped. `callback`
- * will be passed an error, if one occurred, otherwise `null`.
- * @example
- *
- * var count = 0;
- *
- * async.during(
- * function (callback) {
- * return callback(null, count < 5);
- * },
- * function (callback) {
- * count++;
- * setTimeout(callback, 1000);
- * },
- * function (err) {
- * // 5 seconds have passed
- * }
- * );
- */
-function during(test, fn, callback) {
- callback = onlyOnce(callback || noop);
- var _fn = wrapAsync(fn);
- var _test = wrapAsync(test);
-
- function next(err) {
- if (err) return callback(err);
- _test(check);
- }
-
- function check(err, truth) {
- if (err) return callback(err);
- if (!truth) return callback(null);
- _fn(next);
- }
-
- _test(check);
-}
-function _withoutIndex(iteratee) {
- return function (value, index, callback) {
- return iteratee(value, callback);
+ async.parallelLimit = function(tasks, limit, callback) {
+ _parallel(_eachOfLimit(limit), tasks, callback);
};
-}
-
-/**
- * Applies the function `iteratee` to each item in `coll`, in parallel.
- * The `iteratee` is called with an item from the list, and a callback for when
- * it has finished. If the `iteratee` passes an error to its `callback`, the
- * main `callback` (for the `each` function) is immediately called with the
- * error.
- *
- * Note, that since this function applies `iteratee` to each item in parallel,
- * there is no guarantee that the iteratee functions will complete in order.
- *
- * @name each
- * @static
- * @memberOf module:Collections
- * @method
- * @alias forEach
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to
- * each item in `coll`. Invoked with (item, callback).
- * The array index is not passed to the iteratee.
- * If you need the index, use `eachOf`.
- * @param {Function} [callback] - A callback which is called when all
- * `iteratee` functions have finished, or an error occurs. Invoked with (err).
- * @example
- *
- * // assuming openFiles is an array of file names and saveFile is a function
- * // to save the modified contents of that file:
- *
- * async.each(openFiles, saveFile, function(err){
- * // if any of the saves produced an error, err would equal that error
- * });
- *
- * // assuming openFiles is an array of file names
- * async.each(openFiles, function(file, callback) {
- *
- * // Perform operation on file here.
- * console.log('Processing file ' + file);
- *
- * if( file.length > 32 ) {
- * console.log('This file name is too long');
- * callback('File name too long');
- * } else {
- * // Do work to process file here
- * console.log('File processed');
- * callback();
- * }
- * }, function(err) {
- * // if any of the file processing produced an error, err would equal that error
- * if( err ) {
- * // One of the iterations produced an error.
- * // All processing will now stop.
- * console.log('A file failed to process');
- * } else {
- * console.log('All files have been processed successfully');
- * }
- * });
- */
-function eachLimit(coll, iteratee, callback) {
- eachOf(coll, _withoutIndex(wrapAsync(iteratee)), callback);
-}
-/**
- * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
- *
- * @name eachLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.each]{@link module:Collections.each}
- * @alias forEachLimit
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The array index is not passed to the iteratee.
- * If you need the index, use `eachOfLimit`.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called when all
- * `iteratee` functions have finished, or an error occurs. Invoked with (err).
- */
-function eachLimit$1(coll, limit, iteratee, callback) {
- _eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
-}
+ async.series = function(tasks, callback) {
+ _parallel(async.eachOfSeries, tasks, callback);
+ };
-/**
- * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
- *
- * @name eachSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.each]{@link module:Collections.each}
- * @alias forEachSeries
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to each
- * item in `coll`.
- * The array index is not passed to the iteratee.
- * If you need the index, use `eachOfSeries`.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called when all
- * `iteratee` functions have finished, or an error occurs. Invoked with (err).
- */
-var eachSeries = doLimit(eachLimit$1, 1);
-
-/**
- * Wrap an async function and ensure it calls its callback on a later tick of
- * the event loop. If the function already calls its callback on a next tick,
- * no extra deferral is added. This is useful for preventing stack overflows
- * (`RangeError: Maximum call stack size exceeded`) and generally keeping
- * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
- * contained. ES2017 `async` functions are returned as-is -- they are immune
- * to Zalgo's corrupting influences, as they always resolve on a later tick.
- *
- * @name ensureAsync
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {AsyncFunction} fn - an async function, one that expects a node-style
- * callback as its last argument.
- * @returns {AsyncFunction} Returns a wrapped function with the exact same call
- * signature as the function passed in.
- * @example
- *
- * function sometimesAsync(arg, callback) {
- * if (cache[arg]) {
- * return callback(null, cache[arg]); // this would be synchronous!!
- * } else {
- * doSomeIO(arg, callback); // this IO would be asynchronous
- * }
- * }
- *
- * // this has a risk of stack overflows if many results are cached in a row
- * async.mapSeries(args, sometimesAsync, done);
- *
- * // this will defer sometimesAsync's callback if necessary,
- * // preventing stack overflows
- * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
- */
-function ensureAsync(fn) {
- if (isAsync(fn)) return fn;
- return initialParams(function (args, callback) {
- var sync = true;
- args.push(function () {
- var innerArgs = arguments;
- if (sync) {
- setImmediate$1(function () {
- callback.apply(null, innerArgs);
- });
- } else {
- callback.apply(null, innerArgs);
+ async.iterator = function (tasks) {
+ function makeCallback(index) {
+ function fn() {
+ if (tasks.length) {
+ tasks[index].apply(null, arguments);
+ }
+ return fn.next();
}
- });
- fn.apply(this, args);
- sync = false;
- });
-}
-
-function notId(v) {
- return !v;
-}
-
-/**
- * Returns `true` if every element in `coll` satisfies an async test. If any
- * iteratee call returns `false`, the main `callback` is immediately called.
- *
- * @name every
- * @static
- * @memberOf module:Collections
- * @method
- * @alias all
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async truth test to apply to each item
- * in the collection in parallel.
- * The iteratee must complete with a boolean result value.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Result will be either `true` or `false`
- * depending on the values of the async tests. Invoked with (err, result).
- * @example
- *
- * async.every(['file1','file2','file3'], function(filePath, callback) {
- * fs.access(filePath, function(err) {
- * callback(null, !err)
- * });
- * }, function(err, result) {
- * // if result is true then every file exists
- * });
- */
-var every = doParallel(_createTester(notId, notId));
-
-/**
- * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
- *
- * @name everyLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.every]{@link module:Collections.every}
- * @alias allLimit
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async truth test to apply to each item
- * in the collection in parallel.
- * The iteratee must complete with a boolean result value.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Result will be either `true` or `false`
- * depending on the values of the async tests. Invoked with (err, result).
- */
-var everyLimit = doParallelLimit(_createTester(notId, notId));
-
-/**
- * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
- *
- * @name everySeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.every]{@link module:Collections.every}
- * @alias allSeries
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async truth test to apply to each item
- * in the collection in series.
- * The iteratee must complete with a boolean result value.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Result will be either `true` or `false`
- * depending on the values of the async tests. Invoked with (err, result).
- */
-var everySeries = doLimit(everyLimit, 1);
-
-/**
- * The base implementation of `_.property` without support for deep paths.
- *
- * @private
- * @param {string} key The key of the property to get.
- * @returns {Function} Returns the new accessor function.
- */
-function baseProperty(key) {
- return function(object) {
- return object == null ? undefined : object[key];
- };
-}
-
-function filterArray(eachfn, arr, iteratee, callback) {
- var truthValues = new Array(arr.length);
- eachfn(arr, function (x, index, callback) {
- iteratee(x, function (err, v) {
- truthValues[index] = !!v;
- callback(err);
- });
- }, function (err) {
- if (err) return callback(err);
- var results = [];
- for (var i = 0; i < arr.length; i++) {
- if (truthValues[i]) results.push(arr[i]);
+ fn.next = function () {
+ return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+ };
+ return fn;
}
- callback(null, results);
- });
-}
+ return makeCallback(0);
+ };
-function filterGeneric(eachfn, coll, iteratee, callback) {
- var results = [];
- eachfn(coll, function (x, index, callback) {
- iteratee(x, function (err, v) {
- if (err) {
- callback(err);
- } else {
- if (v) {
- results.push({index: index, value: x});
- }
- callback();
- }
+ async.apply = _restParam(function (fn, args) {
+ return _restParam(function (callArgs) {
+ return fn.apply(
+ null, args.concat(callArgs)
+ );
});
- }, function (err) {
- if (err) {
- callback(err);
- } else {
- callback(null, arrayMap(results.sort(function (a, b) {
- return a.index - b.index;
- }), baseProperty('value')));
- }
});
-}
-
-function _filter(eachfn, coll, iteratee, callback) {
- var filter = isArrayLike(coll) ? filterArray : filterGeneric;
- filter(eachfn, coll, wrapAsync(iteratee), callback || noop);
-}
-
-/**
- * Returns a new array of all the values in `coll` which pass an async truth
- * test. This operation is performed in parallel, but the results array will be
- * in the same order as the original.
- *
- * @name filter
- * @static
- * @memberOf module:Collections
- * @method
- * @alias select
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
- * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
- * with a boolean argument once it has completed. Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Invoked with (err, results).
- * @example
- *
- * async.filter(['file1','file2','file3'], function(filePath, callback) {
- * fs.access(filePath, function(err) {
- * callback(null, !err)
- * });
- * }, function(err, results) {
- * // results now equals an array of the existing files
- * });
- */
-var filter = doParallel(_filter);
-
-/**
- * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name filterLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.filter]{@link module:Collections.filter}
- * @alias selectLimit
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
- * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
- * with a boolean argument once it has completed. Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Invoked with (err, results).
- */
-var filterLimit = doParallelLimit(_filter);
-
-/**
- * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
- *
- * @name filterSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.filter]{@link module:Collections.filter}
- * @alias selectSeries
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
- * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
- * with a boolean argument once it has completed. Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Invoked with (err, results)
- */
-var filterSeries = doLimit(filterLimit, 1);
-/**
- * Calls the asynchronous function `fn` with a callback parameter that allows it
- * to call itself again, in series, indefinitely.
-
- * If an error is passed to the callback then `errback` is called with the
- * error, and execution stops, otherwise it will never be called.
- *
- * @name forever
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {AsyncFunction} fn - an async function to call repeatedly.
- * Invoked with (next).
- * @param {Function} [errback] - when `fn` passes an error to it's callback,
- * this function will be called, and execution stops. Invoked with (err).
- * @example
- *
- * async.forever(
- * function(next) {
- * // next is suitable for passing to things that need a callback(err [, whatever]);
- * // it will result in this function being called again.
- * },
- * function(err) {
- * // if next is called with a value in its first parameter, it will appear
- * // in here as 'err', and execution will stop.
- * }
- * );
- */
-function forever(fn, errback) {
- var done = onlyOnce(errback || noop);
- var task = wrapAsync(ensureAsync(fn));
-
- function next(err) {
- if (err) return done(err);
- task(next);
+ function _concat(eachfn, arr, fn, callback) {
+ var result = [];
+ eachfn(arr, function (x, index, cb) {
+ fn(x, function (err, y) {
+ result = result.concat(y || []);
+ cb(err);
+ });
+ }, function (err) {
+ callback(err, result);
+ });
}
- next();
-}
+ async.concat = doParallel(_concat);
+ async.concatSeries = doSeries(_concat);
-/**
- * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
- *
- * @name groupByLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.groupBy]{@link module:Collections.groupBy}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with a `key` to group the value under.
- * Invoked with (value, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Result is an `Object` whoses
- * properties are arrays of values which returned the corresponding key.
- */
-var groupByLimit = function(coll, limit, iteratee, callback) {
- callback = callback || noop;
- var _iteratee = wrapAsync(iteratee);
- mapLimit(coll, limit, function(val, callback) {
- _iteratee(val, function(err, key) {
- if (err) return callback(err);
- return callback(null, {key: key, val: val});
- });
- }, function(err, mapResults) {
- var result = {};
- // from MDN, handle object having an `hasOwnProperty` prop
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- for (var i = 0; i < mapResults.length; i++) {
- if (mapResults[i]) {
- var key = mapResults[i].key;
- var val = mapResults[i].val;
-
- if (hasOwnProperty.call(result, key)) {
- result[key].push(val);
+ async.whilst = function (test, iterator, callback) {
+ callback = callback || noop;
+ if (test()) {
+ var next = _restParam(function(err, args) {
+ if (err) {
+ callback(err);
+ } else if (test.apply(this, args)) {
+ iterator(next);
} else {
- result[key] = [val];
+ callback.apply(null, [null].concat(args));
}
- }
+ });
+ iterator(next);
+ } else {
+ callback(null);
}
+ };
- return callback(err, result);
- });
-};
+ async.doWhilst = function (iterator, test, callback) {
+ var calls = 0;
+ return async.whilst(function() {
+ return ++calls <= 1 || test.apply(this, arguments);
+ }, iterator, callback);
+ };
-/**
- * Returns a new object, where each value corresponds to an array of items, from
- * `coll`, that returned the corresponding key. That is, the keys of the object
- * correspond to the values passed to the `iteratee` callback.
- *
- * Note: Since this function applies the `iteratee` to each item in parallel,
- * there is no guarantee that the `iteratee` functions will complete in order.
- * However, the values for each key in the `result` will be in the same order as
- * the original `coll`. For Objects, the values will roughly be in the order of
- * the original Objects' keys (but this can vary across JavaScript engines).
- *
- * @name groupBy
- * @static
- * @memberOf module:Collections
- * @method
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with a `key` to group the value under.
- * Invoked with (value, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Result is an `Object` whoses
- * properties are arrays of values which returned the corresponding key.
- * @example
- *
- * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) {
- * db.findById(userId, function(err, user) {
- * if (err) return callback(err);
- * return callback(null, user.age);
- * });
- * }, function(err, result) {
- * // result is object containing the userIds grouped by age
- * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']};
- * });
- */
-var groupBy = doLimit(groupByLimit, Infinity);
+ async.until = function (test, iterator, callback) {
+ return async.whilst(function() {
+ return !test.apply(this, arguments);
+ }, iterator, callback);
+ };
-/**
- * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
- *
- * @name groupBySeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.groupBy]{@link module:Collections.groupBy}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with a `key` to group the value under.
- * Invoked with (value, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. Result is an `Object` whoses
- * properties are arrays of values which returned the corresponding key.
- */
-var groupBySeries = doLimit(groupByLimit, 1);
+ async.doUntil = function (iterator, test, callback) {
+ return async.doWhilst(iterator, function() {
+ return !test.apply(this, arguments);
+ }, callback);
+ };
-/**
- * Logs the result of an `async` function to the `console`. Only works in
- * Node.js or in browsers that support `console.log` and `console.error` (such
- * as FF and Chrome). If multiple arguments are returned from the async
- * function, `console.log` is called on each argument in order.
- *
- * @name log
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {AsyncFunction} function - The function you want to eventually apply
- * all arguments to.
- * @param {...*} arguments... - Any number of arguments to apply to the function.
- * @example
- *
- * // in a module
- * var hello = function(name, callback) {
- * setTimeout(function() {
- * callback(null, 'hello ' + name);
- * }, 1000);
- * };
- *
- * // in the node repl
- * node> async.log(hello, 'world');
- * 'hello world'
- */
-var log = consoleFunc('log');
+ async.during = function (test, iterator, callback) {
+ callback = callback || noop;
-/**
- * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name mapValuesLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.mapValues]{@link module:Collections.mapValues}
- * @category Collection
- * @param {Object} obj - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - A function to apply to each value and key
- * in `coll`.
- * The iteratee should complete with the transformed value as its result.
- * Invoked with (value, key, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. `result` is a new object consisting
- * of each key from `obj`, with each transformed value on the right-hand side.
- * Invoked with (err, result).
- */
-function mapValuesLimit(obj, limit, iteratee, callback) {
- callback = once(callback || noop);
- var newObj = {};
- var _iteratee = wrapAsync(iteratee);
- eachOfLimit(obj, limit, function(val, key, next) {
- _iteratee(val, key, function (err, result) {
- if (err) return next(err);
- newObj[key] = result;
- next();
+ var next = _restParam(function(err, args) {
+ if (err) {
+ callback(err);
+ } else {
+ args.push(check);
+ test.apply(this, args);
+ }
});
- }, function (err) {
- callback(err, newObj);
- });
-}
-
-/**
- * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.
- *
- * Produces a new Object by mapping each value of `obj` through the `iteratee`
- * function. The `iteratee` is called each `value` and `key` from `obj` and a
- * callback for when it has finished processing. Each of these callbacks takes
- * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`
- * passes an error to its callback, the main `callback` (for the `mapValues`
- * function) is immediately called with the error.
- *
- * Note, the order of the keys in the result is not guaranteed. The keys will
- * be roughly in the order they complete, (but this is very engine-specific)
- *
- * @name mapValues
- * @static
- * @memberOf module:Collections
- * @method
- * @category Collection
- * @param {Object} obj - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A function to apply to each value and key
- * in `coll`.
- * The iteratee should complete with the transformed value as its result.
- * Invoked with (value, key, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. `result` is a new object consisting
- * of each key from `obj`, with each transformed value on the right-hand side.
- * Invoked with (err, result).
- * @example
- *
- * async.mapValues({
- * f1: 'file1',
- * f2: 'file2',
- * f3: 'file3'
- * }, function (file, key, callback) {
- * fs.stat(file, callback);
- * }, function(err, result) {
- * // result is now a map of stats for each file, e.g.
- * // {
- * // f1: [stats for file1],
- * // f2: [stats for file2],
- * // f3: [stats for file3]
- * // }
- * });
- */
-
-var mapValues = doLimit(mapValuesLimit, Infinity);
-/**
- * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.
- *
- * @name mapValuesSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.mapValues]{@link module:Collections.mapValues}
- * @category Collection
- * @param {Object} obj - A collection to iterate over.
- * @param {AsyncFunction} iteratee - A function to apply to each value and key
- * in `coll`.
- * The iteratee should complete with the transformed value as its result.
- * Invoked with (value, key, callback).
- * @param {Function} [callback] - A callback which is called when all `iteratee`
- * functions have finished, or an error occurs. `result` is a new object consisting
- * of each key from `obj`, with each transformed value on the right-hand side.
- * Invoked with (err, result).
- */
-var mapValuesSeries = doLimit(mapValuesLimit, 1);
+ var check = function(err, truth) {
+ if (err) {
+ callback(err);
+ } else if (truth) {
+ iterator(next);
+ } else {
+ callback(null);
+ }
+ };
-function has(obj, key) {
- return key in obj;
-}
+ test(check);
+ };
-/**
- * Caches the results of an async function. When creating a hash to store
- * function results against, the callback is omitted from the hash and an
- * optional hash function can be used.
- *
- * If no hash function is specified, the first argument is used as a hash key,
- * which may work reasonably if it is a string or a data type that converts to a
- * distinct string. Note that objects and arrays will not behave reasonably.
- * Neither will cases where the other arguments are significant. In such cases,
- * specify your own hash function.
- *
- * The cache of results is exposed as the `memo` property of the function
- * returned by `memoize`.
- *
- * @name memoize
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {AsyncFunction} fn - The async function to proxy and cache results from.
- * @param {Function} hasher - An optional function for generating a custom hash
- * for storing results. It has all the arguments applied to it apart from the
- * callback, and must be synchronous.
- * @returns {AsyncFunction} a memoized version of `fn`
- * @example
- *
- * var slow_fn = function(name, callback) {
- * // do something
- * callback(null, result);
- * };
- * var fn = async.memoize(slow_fn);
- *
- * // fn can now be used as if it were slow_fn
- * fn('some name', function() {
- * // callback
- * });
- */
-function memoize(fn, hasher) {
- var memo = Object.create(null);
- var queues = Object.create(null);
- hasher = hasher || identity;
- var _fn = wrapAsync(fn);
- var memoized = initialParams(function memoized(args, callback) {
- var key = hasher.apply(null, args);
- if (has(memo, key)) {
- setImmediate$1(function() {
- callback.apply(null, memo[key]);
- });
- } else if (has(queues, key)) {
- queues[key].push(callback);
- } else {
- queues[key] = [callback];
- _fn.apply(null, args.concat(function(/*args*/) {
- var args = slice(arguments);
- memo[key] = args;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, args);
- }
- }));
- }
- });
- memoized.memo = memo;
- memoized.unmemoized = fn;
- return memoized;
-}
-
-/**
- * Calls `callback` on a later loop around the event loop. In Node.js this just
- * calls `setImmediate`. In the browser it will use `setImmediate` if
- * available, otherwise `setTimeout(callback, 0)`, which means other higher
- * priority events may precede the execution of `callback`.
- *
- * This is used internally for browser-compatibility purposes.
- *
- * @name nextTick
- * @static
- * @memberOf module:Utils
- * @method
- * @alias setImmediate
- * @category Util
- * @param {Function} callback - The function to call on a later loop around
- * the event loop. Invoked with (args...).
- * @param {...*} args... - any number of additional arguments to pass to the
- * callback on the next tick.
- * @example
- *
- * var call_order = [];
- * async.nextTick(function() {
- * call_order.push('two');
- * // call_order now equals ['one','two']
- * });
- * call_order.push('one');
- *
- * async.setImmediate(function (a, b, c) {
- * // a, b, and c equal 1, 2, and 3
- * }, 1, 2, 3);
- */
-var _defer$1;
-
-if (hasNextTick) {
- _defer$1 = process.nextTick;
-} else if (hasSetImmediate) {
- _defer$1 = setImmediate;
-} else {
- _defer$1 = fallback;
-}
-
-var nextTick = wrap(_defer$1);
-
-function _parallel(eachfn, tasks, callback) {
- callback = callback || noop;
- var results = isArrayLike(tasks) ? [] : {};
-
- eachfn(tasks, function (task, key, callback) {
- wrapAsync(task)(function (err, result) {
- if (arguments.length > 2) {
- result = slice(arguments, 1);
+ async.doDuring = function (iterator, test, callback) {
+ var calls = 0;
+ async.during(function(next) {
+ if (calls++ < 1) {
+ next(null, true);
+ } else {
+ test.apply(this, arguments);
}
- results[key] = result;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
-}
-
-/**
- * Run the `tasks` collection of functions in parallel, without waiting until
- * the previous function has completed. If any of the functions pass an error to
- * its callback, the main `callback` is immediately called with the value of the
- * error. Once the `tasks` have completed, the results are passed to the final
- * `callback` as an array.
- *
- * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about
- * parallel execution of code. If your tasks do not use any timers or perform
- * any I/O, they will actually be executed in series. Any synchronous setup
- * sections for each task will happen one after the other. JavaScript remains
- * single-threaded.
- *
- * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
- * execution of other tasks when a task fails.
- *
- * It is also possible to use an object instead of an array. Each property will
- * be run as a function and the results will be passed to the final `callback`
- * as an object instead of an array. This can be a more readable way of handling
- * results from {@link async.parallel}.
- *
- * @name parallel
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Array|Iterable|Object} tasks - A collection of
- * [async functions]{@link AsyncFunction} to run.
- * Each async function can complete with any number of optional `result` values.
- * @param {Function} [callback] - An optional callback to run once all the
- * functions have completed successfully. This function gets a results array
- * (or object) containing all the result arguments passed to the task callbacks.
- * Invoked with (err, results).
- *
- * @example
- * async.parallel([
- * function(callback) {
- * setTimeout(function() {
- * callback(null, 'one');
- * }, 200);
- * },
- * function(callback) {
- * setTimeout(function() {
- * callback(null, 'two');
- * }, 100);
- * }
- * ],
- * // optional callback
- * function(err, results) {
- * // the results array will equal ['one','two'] even though
- * // the second function had a shorter timeout.
- * });
- *
- * // an example using an object instead of an array
- * async.parallel({
- * one: function(callback) {
- * setTimeout(function() {
- * callback(null, 1);
- * }, 200);
- * },
- * two: function(callback) {
- * setTimeout(function() {
- * callback(null, 2);
- * }, 100);
- * }
- * }, function(err, results) {
- * // results is now equals to: {one: 1, two: 2}
- * });
- */
-function parallelLimit(tasks, callback) {
- _parallel(eachOf, tasks, callback);
-}
-
-/**
- * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name parallelLimit
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.parallel]{@link module:ControlFlow.parallel}
- * @category Control Flow
- * @param {Array|Iterable|Object} tasks - A collection of
- * [async functions]{@link AsyncFunction} to run.
- * Each async function can complete with any number of optional `result` values.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {Function} [callback] - An optional callback to run once all the
- * functions have completed successfully. This function gets a results array
- * (or object) containing all the result arguments passed to the task callbacks.
- * Invoked with (err, results).
- */
-function parallelLimit$1(tasks, limit, callback) {
- _parallel(_eachOfLimit(limit), tasks, callback);
-}
-
-/**
- * A queue of tasks for the worker function to complete.
- * @typedef {Object} QueueObject
- * @memberOf module:ControlFlow
- * @property {Function} length - a function returning the number of items
- * waiting to be processed. Invoke with `queue.length()`.
- * @property {boolean} started - a boolean indicating whether or not any
- * items have been pushed and processed by the queue.
- * @property {Function} running - a function returning the number of items
- * currently being processed. Invoke with `queue.running()`.
- * @property {Function} workersList - a function returning the array of items
- * currently being processed. Invoke with `queue.workersList()`.
- * @property {Function} idle - a function returning false if there are items
- * waiting or being processed, or true if not. Invoke with `queue.idle()`.
- * @property {number} concurrency - an integer for determining how many `worker`
- * functions should be run in parallel. This property can be changed after a
- * `queue` is created to alter the concurrency on-the-fly.
- * @property {Function} push - add a new task to the `queue`. Calls `callback`
- * once the `worker` has finished processing the task. Instead of a single task,
- * a `tasks` array can be submitted. The respective callback is used for every
- * task in the list. Invoke with `queue.push(task, [callback])`,
- * @property {Function} unshift - add a new task to the front of the `queue`.
- * Invoke with `queue.unshift(task, [callback])`.
- * @property {Function} remove - remove items from the queue that match a test
- * function. The test function will be passed an object with a `data` property,
- * and a `priority` property, if this is a
- * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
- * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
- * `function ({data, priority}) {}` and returns a Boolean.
- * @property {Function} saturated - a callback that is called when the number of
- * running workers hits the `concurrency` limit, and further tasks will be
- * queued.
- * @property {Function} unsaturated - a callback that is called when the number
- * of running workers is less than the `concurrency` & `buffer` limits, and
- * further tasks will not be queued.
- * @property {number} buffer - A minimum threshold buffer in order to say that
- * the `queue` is `unsaturated`.
- * @property {Function} empty - a callback that is called when the last item
- * from the `queue` is given to a `worker`.
- * @property {Function} drain - a callback that is called when the last item
- * from the `queue` has returned from the `worker`.
- * @property {Function} error - a callback that is called when a task errors.
- * Has the signature `function(error, task)`.
- * @property {boolean} paused - a boolean for determining whether the queue is
- * in a paused state.
- * @property {Function} pause - a function that pauses the processing of tasks
- * until `resume()` is called. Invoke with `queue.pause()`.
- * @property {Function} resume - a function that resumes the processing of
- * queued tasks when the queue is paused. Invoke with `queue.resume()`.
- * @property {Function} kill - a function that removes the `drain` callback and
- * empties remaining tasks from the queue forcing it to go idle. No more tasks
- * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.
- */
+ }, iterator, callback);
+ };
-/**
- * Creates a `queue` object with the specified `concurrency`. Tasks added to the
- * `queue` are processed in parallel (up to the `concurrency` limit). If all
- * `worker`s are in progress, the task is queued until one becomes available.
- * Once a `worker` completes a `task`, that `task`'s callback is called.
- *
- * @name queue
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {AsyncFunction} worker - An async function for processing a queued task.
- * If you want to handle errors from an individual task, pass a callback to
- * `q.push()`. Invoked with (task, callback).
- * @param {number} [concurrency=1] - An `integer` for determining how many
- * `worker` functions should be run in parallel. If omitted, the concurrency
- * defaults to `1`. If the concurrency is `0`, an error is thrown.
- * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can
- * attached as certain properties to listen for specific events during the
- * lifecycle of the queue.
- * @example
- *
- * // create a queue object with concurrency 2
- * var q = async.queue(function(task, callback) {
- * console.log('hello ' + task.name);
- * callback();
- * }, 2);
- *
- * // assign a callback
- * q.drain = function() {
- * console.log('all items have been processed');
- * };
- *
- * // add some items to the queue
- * q.push({name: 'foo'}, function(err) {
- * console.log('finished processing foo');
- * });
- * q.push({name: 'bar'}, function (err) {
- * console.log('finished processing bar');
- * });
- *
- * // add some items to the queue (batch-wise)
- * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
- * console.log('finished processing item');
- * });
- *
- * // add some items to the front of the queue
- * q.unshift({name: 'bar'}, function (err) {
- * console.log('finished processing bar');
- * });
- */
-var queue$1 = function (worker, concurrency) {
- var _worker = wrapAsync(worker);
- return queue(function (items, cb) {
- _worker(items[0], cb);
- }, concurrency, 1);
-};
-
-/**
- * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and
- * completed in ascending priority order.
- *
- * @name priorityQueue
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.queue]{@link module:ControlFlow.queue}
- * @category Control Flow
- * @param {AsyncFunction} worker - An async function for processing a queued task.
- * If you want to handle errors from an individual task, pass a callback to
- * `q.push()`.
- * Invoked with (task, callback).
- * @param {number} concurrency - An `integer` for determining how many `worker`
- * functions should be run in parallel. If omitted, the concurrency defaults to
- * `1`. If the concurrency is `0`, an error is thrown.
- * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two
- * differences between `queue` and `priorityQueue` objects:
- * * `push(task, priority, [callback])` - `priority` should be a number. If an
- * array of `tasks` is given, all tasks will be assigned the same priority.
- * * The `unshift` method was removed.
- */
-var priorityQueue = function(worker, concurrency) {
- // Start with a normal queue
- var q = queue$1(worker, concurrency);
-
- // Override push to accept second parameter representing priority
- q.push = function(data, priority, callback) {
- if (callback == null) callback = noop;
- if (typeof callback !== 'function') {
- throw new Error('task callback must be a function');
+ function _queue(worker, concurrency, payload) {
+ if (concurrency == null) {
+ concurrency = 1;
}
- q.started = true;
- if (!isArray(data)) {
- data = [data];
+ else if(concurrency === 0) {
+ throw new Error('Concurrency must not be zero');
}
- if (data.length === 0) {
- // call drain immediately if there are no tasks
- return setImmediate$1(function() {
- q.drain();
+ function _insert(q, data, pos, callback) {
+ if (callback != null && typeof callback !== "function") {
+ throw new Error("task callback must be a function");
+ }
+ q.started = true;
+ if (!_isArray(data)) {
+ data = [data];
+ }
+ if(data.length === 0 && q.idle()) {
+ // call drain immediately if there are no tasks
+ return async.setImmediate(function() {
+ q.drain();
+ });
+ }
+ _arrayEach(data, function(task) {
+ var item = {
+ data: task,
+ callback: callback || noop
+ };
+
+ if (pos) {
+ q.tasks.unshift(item);
+ } else {
+ q.tasks.push(item);
+ }
+
+ if (q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
});
+ async.setImmediate(q.process);
}
+ function _next(q, tasks) {
+ return function(){
+ workers -= 1;
+
+ var removed = false;
+ var args = arguments;
+ _arrayEach(tasks, function (task) {
+ _arrayEach(workersList, function (worker, index) {
+ if (worker === task && !removed) {
+ workersList.splice(index, 1);
+ removed = true;
+ }
+ });
- priority = priority || 0;
- var nextNode = q._tasks.head;
- while (nextNode && priority >= nextNode.priority) {
- nextNode = nextNode.next;
+ task.callback.apply(task, args);
+ });
+ if (q.tasks.length + workers === 0) {
+ q.drain();
+ }
+ q.process();
+ };
}
- for (var i = 0, l = data.length; i < l; i++) {
- var item = {
- data: data[i],
- priority: priority,
- callback: callback
- };
+ var workers = 0;
+ var workersList = [];
+ var q = {
+ tasks: [],
+ concurrency: concurrency,
+ payload: payload,
+ saturated: noop,
+ empty: noop,
+ drain: noop,
+ started: false,
+ paused: false,
+ push: function (data, callback) {
+ _insert(q, data, false, callback);
+ },
+ kill: function () {
+ q.drain = noop;
+ q.tasks = [];
+ },
+ unshift: function (data, callback) {
+ _insert(q, data, true, callback);
+ },
+ process: function () {
+ while(!q.paused && workers < q.concurrency && q.tasks.length){
+
+ var tasks = q.payload ?
+ q.tasks.splice(0, q.payload) :
+ q.tasks.splice(0, q.tasks.length);
+
+ var data = _map(tasks, function (task) {
+ return task.data;
+ });
- if (nextNode) {
- q._tasks.insertBefore(nextNode, item);
- } else {
- q._tasks.push(item);
+ if (q.tasks.length === 0) {
+ q.empty();
+ }
+ workers += 1;
+ workersList.push(tasks[0]);
+ var cb = only_once(_next(q, tasks));
+ worker(data, cb);
+ }
+ },
+ length: function () {
+ return q.tasks.length;
+ },
+ running: function () {
+ return workers;
+ },
+ workersList: function () {
+ return workersList;
+ },
+ idle: function() {
+ return q.tasks.length + workers === 0;
+ },
+ pause: function () {
+ q.paused = true;
+ },
+ resume: function () {
+ if (q.paused === false) { return; }
+ q.paused = false;
+ var resumeCount = Math.min(q.concurrency, q.tasks.length);
+ // Need to call q.process once per concurrent
+ // worker to preserve full concurrency after pause
+ for (var w = 1; w <= resumeCount; w++) {
+ async.setImmediate(q.process);
+ }
}
- }
- setImmediate$1(q.process);
- };
+ };
+ return q;
+ }
- // Remove unshift function
- delete q.unshift;
+ async.queue = function (worker, concurrency) {
+ var q = _queue(function (items, cb) {
+ worker(items[0], cb);
+ }, concurrency, 1);
- return q;
-};
+ return q;
+ };
-/**
- * Runs the `tasks` array of functions in parallel, without waiting until the
- * previous function has completed. Once any of the `tasks` complete or pass an
- * error to its callback, the main `callback` is immediately called. It's
- * equivalent to `Promise.race()`.
- *
- * @name race
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
- * to run. Each function can complete with an optional `result` value.
- * @param {Function} callback - A callback to run once any of the functions have
- * completed. This function gets an error or result from the first function that
- * completed. Invoked with (err, result).
- * @returns undefined
- * @example
- *
- * async.race([
- * function(callback) {
- * setTimeout(function() {
- * callback(null, 'one');
- * }, 200);
- * },
- * function(callback) {
- * setTimeout(function() {
- * callback(null, 'two');
- * }, 100);
- * }
- * ],
- * // main callback
- * function(err, result) {
- * // the result will be equal to 'two' as it finishes earlier
- * });
- */
-function race(tasks, callback) {
- callback = once(callback || noop);
- if (!isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
- if (!tasks.length) return callback();
- for (var i = 0, l = tasks.length; i < l; i++) {
- wrapAsync(tasks[i])(callback);
- }
-}
+ async.priorityQueue = function (worker, concurrency) {
-/**
- * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
- *
- * @name reduceRight
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.reduce]{@link module:Collections.reduce}
- * @alias foldr
- * @category Collection
- * @param {Array} array - A collection to iterate over.
- * @param {*} memo - The initial state of the reduction.
- * @param {AsyncFunction} iteratee - A function applied to each item in the
- * array to produce the next step in the reduction.
- * The `iteratee` should complete with the next state of the reduction.
- * If the iteratee complete with an error, the reduction is stopped and the
- * main `callback` is immediately called with the error.
- * Invoked with (memo, item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Result is the reduced value. Invoked with
- * (err, result).
- */
-function reduceRight (array, memo, iteratee, callback) {
- var reversed = slice(array).reverse();
- reduce(reversed, memo, iteratee, callback);
-}
-
-/**
- * Wraps the async function in another function that always completes with a
- * result object, even when it errors.
- *
- * The result object has either the property `error` or `value`.
- *
- * @name reflect
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {AsyncFunction} fn - The async function you want to wrap
- * @returns {Function} - A function that always passes null to it's callback as
- * the error. The second argument to the callback will be an `object` with
- * either an `error` or a `value` property.
- * @example
- *
- * async.parallel([
- * async.reflect(function(callback) {
- * // do some stuff ...
- * callback(null, 'one');
- * }),
- * async.reflect(function(callback) {
- * // do some more stuff but error ...
- * callback('bad stuff happened');
- * }),
- * async.reflect(function(callback) {
- * // do some more stuff ...
- * callback(null, 'two');
- * })
- * ],
- * // optional callback
- * function(err, results) {
- * // values
- * // results[0].value = 'one'
- * // results[1].error = 'bad stuff happened'
- * // results[2].value = 'two'
- * });
- */
-function reflect(fn) {
- var _fn = wrapAsync(fn);
- return initialParams(function reflectOn(args, reflectCallback) {
- args.push(function callback(error, cbArg) {
- if (error) {
- reflectCallback(null, { error: error });
- } else {
- var value;
- if (arguments.length <= 2) {
- value = cbArg;
+ function _compareTasks(a, b){
+ return a.priority - b.priority;
+ }
+
+ function _binarySearch(sequence, item, compare) {
+ var beg = -1,
+ end = sequence.length - 1;
+ while (beg < end) {
+ var mid = beg + ((end - beg + 1) >>> 1);
+ if (compare(item, sequence[mid]) >= 0) {
+ beg = mid;
} else {
- value = slice(arguments, 1);
+ end = mid - 1;
}
- reflectCallback(null, { value: value });
}
- });
-
- return _fn.apply(this, args);
- });
-}
+ return beg;
+ }
-function reject$1(eachfn, arr, iteratee, callback) {
- _filter(eachfn, arr, function(value, cb) {
- iteratee(value, function(err, v) {
- cb(err, !v);
- });
- }, callback);
-}
+ function _insert(q, data, priority, callback) {
+ if (callback != null && typeof callback !== "function") {
+ throw new Error("task callback must be a function");
+ }
+ q.started = true;
+ if (!_isArray(data)) {
+ data = [data];
+ }
+ if(data.length === 0) {
+ // call drain immediately if there are no tasks
+ return async.setImmediate(function() {
+ q.drain();
+ });
+ }
+ _arrayEach(data, function(task) {
+ var item = {
+ data: task,
+ priority: priority,
+ callback: typeof callback === 'function' ? callback : noop
+ };
-/**
- * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
- *
- * @name reject
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.filter]{@link module:Collections.filter}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {Function} iteratee - An async truth test to apply to each item in
- * `coll`.
- * The should complete with a boolean value as its `result`.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Invoked with (err, results).
- * @example
- *
- * async.reject(['file1','file2','file3'], function(filePath, callback) {
- * fs.access(filePath, function(err) {
- * callback(null, !err)
- * });
- * }, function(err, results) {
- * // results now equals an array of missing files
- * createFiles(results);
- * });
- */
-var reject = doParallel(reject$1);
+ q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
-/**
- * A helper function that wraps an array or an object of functions with `reflect`.
- *
- * @name reflectAll
- * @static
- * @memberOf module:Utils
- * @method
- * @see [async.reflect]{@link module:Utils.reflect}
- * @category Util
- * @param {Array|Object|Iterable} tasks - The collection of
- * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
- * @returns {Array} Returns an array of async functions, each wrapped in
- * `async.reflect`
- * @example
- *
- * let tasks = [
- * function(callback) {
- * setTimeout(function() {
- * callback(null, 'one');
- * }, 200);
- * },
- * function(callback) {
- * // do some more stuff but error ...
- * callback(new Error('bad stuff happened'));
- * },
- * function(callback) {
- * setTimeout(function() {
- * callback(null, 'two');
- * }, 100);
- * }
- * ];
- *
- * async.parallel(async.reflectAll(tasks),
- * // optional callback
- * function(err, results) {
- * // values
- * // results[0].value = 'one'
- * // results[1].error = Error('bad stuff happened')
- * // results[2].value = 'two'
- * });
- *
- * // an example using an object instead of an array
- * let tasks = {
- * one: function(callback) {
- * setTimeout(function() {
- * callback(null, 'one');
- * }, 200);
- * },
- * two: function(callback) {
- * callback('two');
- * },
- * three: function(callback) {
- * setTimeout(function() {
- * callback(null, 'three');
- * }, 100);
- * }
- * };
- *
- * async.parallel(async.reflectAll(tasks),
- * // optional callback
- * function(err, results) {
- * // values
- * // results.one.value = 'one'
- * // results.two.error = 'two'
- * // results.three.value = 'three'
- * });
- */
-function reflectAll(tasks) {
- var results;
- if (isArray(tasks)) {
- results = arrayMap(tasks, reflect);
- } else {
- results = {};
- baseForOwn(tasks, function(task, key) {
- results[key] = reflect.call(this, task);
- });
- }
- return results;
-}
+ if (q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ async.setImmediate(q.process);
+ });
+ }
-/**
- * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name rejectLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.reject]{@link module:Collections.reject}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {Function} iteratee - An async truth test to apply to each item in
- * `coll`.
- * The should complete with a boolean value as its `result`.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Invoked with (err, results).
- */
-var rejectLimit = doParallelLimit(reject$1);
+ // Start with a normal queue
+ var q = async.queue(worker, concurrency);
-/**
- * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
- *
- * @name rejectSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.reject]{@link module:Collections.reject}
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {Function} iteratee - An async truth test to apply to each item in
- * `coll`.
- * The should complete with a boolean value as its `result`.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Invoked with (err, results).
- */
-var rejectSeries = doLimit(rejectLimit, 1);
+ // Override push to accept second parameter representing priority
+ q.push = function (data, priority, callback) {
+ _insert(q, data, priority, callback);
+ };
-/**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @since 2.4.0
- * @category Util
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new constant function.
- * @example
- *
- * var objects = _.times(2, _.constant({ 'a': 1 }));
- *
- * console.log(objects);
- * // => [{ 'a': 1 }, { 'a': 1 }]
- *
- * console.log(objects[0] === objects[1]);
- * // => true
- */
-function constant$1(value) {
- return function() {
- return value;
- };
-}
-
-/**
- * Attempts to get a successful response from `task` no more than `times` times
- * before returning an error. If the task is successful, the `callback` will be
- * passed the result of the successful task. If all attempts fail, the callback
- * will be passed the error and result (if any) of the final attempt.
- *
- * @name retry
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @see [async.retryable]{@link module:ControlFlow.retryable}
- * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
- * object with `times` and `interval` or a number.
- * * `times` - The number of attempts to make before giving up. The default
- * is `5`.
- * * `interval` - The time to wait between retries, in milliseconds. The
- * default is `0`. The interval may also be specified as a function of the
- * retry count (see example).
- * * `errorFilter` - An optional synchronous function that is invoked on
- * erroneous result. If it returns `true` the retry attempts will continue;
- * if the function returns `false` the retry flow is aborted with the current
- * attempt's error and result being returned to the final callback.
- * Invoked with (err).
- * * If `opts` is a number, the number specifies the number of times to retry,
- * with the default interval of `0`.
- * @param {AsyncFunction} task - An async function to retry.
- * Invoked with (callback).
- * @param {Function} [callback] - An optional callback which is called when the
- * task has succeeded, or after the final failed attempt. It receives the `err`
- * and `result` arguments of the last attempt at completing the `task`. Invoked
- * with (err, results).
- *
- * @example
- *
- * // The `retry` function can be used as a stand-alone control flow by passing
- * // a callback, as shown below:
- *
- * // try calling apiMethod 3 times
- * async.retry(3, apiMethod, function(err, result) {
- * // do something with the result
- * });
- *
- * // try calling apiMethod 3 times, waiting 200 ms between each retry
- * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
- * // do something with the result
- * });
- *
- * // try calling apiMethod 10 times with exponential backoff
- * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
- * async.retry({
- * times: 10,
- * interval: function(retryCount) {
- * return 50 * Math.pow(2, retryCount);
- * }
- * }, apiMethod, function(err, result) {
- * // do something with the result
- * });
- *
- * // try calling apiMethod the default 5 times no delay between each retry
- * async.retry(apiMethod, function(err, result) {
- * // do something with the result
- * });
- *
- * // try calling apiMethod only when error condition satisfies, all other
- * // errors will abort the retry control flow and return to final callback
- * async.retry({
- * errorFilter: function(err) {
- * return err.message === 'Temporary error'; // only retry on a specific error
- * }
- * }, apiMethod, function(err, result) {
- * // do something with the result
- * });
- *
- * // It can also be embedded within other control flow functions to retry
- * // individual methods that are not as reliable, like this:
- * async.auto({
- * users: api.getUsers.bind(api),
- * payments: async.retryable(3, api.getPayments.bind(api))
- * }, function(err, results) {
- * // do something with the results
- * });
- *
- */
-function retry(opts, task, callback) {
- var DEFAULT_TIMES = 5;
- var DEFAULT_INTERVAL = 0;
+ // Remove unshift function
+ delete q.unshift;
- var options = {
- times: DEFAULT_TIMES,
- intervalFunc: constant$1(DEFAULT_INTERVAL)
+ return q;
};
- function parseTimes(acc, t) {
- if (typeof t === 'object') {
- acc.times = +t.times || DEFAULT_TIMES;
-
- acc.intervalFunc = typeof t.interval === 'function' ?
- t.interval :
- constant$1(+t.interval || DEFAULT_INTERVAL);
-
- acc.errorFilter = t.errorFilter;
- } else if (typeof t === 'number' || typeof t === 'string') {
- acc.times = +t || DEFAULT_TIMES;
- } else {
- throw new Error("Invalid arguments for async.retry");
- }
- }
-
- if (arguments.length < 3 && typeof opts === 'function') {
- callback = task || noop;
- task = opts;
- } else {
- parseTimes(options, opts);
- callback = callback || noop;
- }
+ async.cargo = function (worker, payload) {
+ return _queue(worker, 1, payload);
+ };
- if (typeof task !== 'function') {
- throw new Error("Invalid arguments for async.retry");
+ function _console_fn(name) {
+ return _restParam(function (fn, args) {
+ fn.apply(null, args.concat([_restParam(function (err, args) {
+ if (typeof console === 'object') {
+ if (err) {
+ if (console.error) {
+ console.error(err);
+ }
+ }
+ else if (console[name]) {
+ _arrayEach(args, function (x) {
+ console[name](x);
+ });
+ }
+ }
+ })]));
+ });
}
-
- var _task = wrapAsync(task);
-
- var attempt = 1;
- function retryAttempt() {
- _task(function(err) {
- if (err && attempt++ < options.times &&
- (typeof options.errorFilter != 'function' ||
- options.errorFilter(err))) {
- setTimeout(retryAttempt, options.intervalFunc(attempt));
- } else {
- callback.apply(null, arguments);
+ async.log = _console_fn('log');
+ async.dir = _console_fn('dir');
+ /*async.info = _console_fn('info');
+ async.warn = _console_fn('warn');
+ async.error = _console_fn('error');*/
+
+ async.memoize = function (fn, hasher) {
+ var memo = {};
+ var queues = {};
+ var has = Object.prototype.hasOwnProperty;
+ hasher = hasher || identity;
+ var memoized = _restParam(function memoized(args) {
+ var callback = args.pop();
+ var key = hasher.apply(null, args);
+ if (has.call(memo, key)) {
+ async.setImmediate(function () {
+ callback.apply(null, memo[key]);
+ });
+ }
+ else if (has.call(queues, key)) {
+ queues[key].push(callback);
+ }
+ else {
+ queues[key] = [callback];
+ fn.apply(null, args.concat([_restParam(function (args) {
+ memo[key] = args;
+ var q = queues[key];
+ delete queues[key];
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i].apply(null, args);
+ }
+ })]));
}
});
- }
+ memoized.memo = memo;
+ memoized.unmemoized = fn;
+ return memoized;
+ };
- retryAttempt();
-}
+ async.unmemoize = function (fn) {
+ return function () {
+ return (fn.unmemoized || fn).apply(null, arguments);
+ };
+ };
-/**
- * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method
- * wraps a task and makes it retryable, rather than immediately calling it
- * with retries.
- *
- * @name retryable
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.retry]{@link module:ControlFlow.retry}
- * @category Control Flow
- * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
- * options, exactly the same as from `retry`
- * @param {AsyncFunction} task - the asynchronous function to wrap.
- * This function will be passed any arguments passed to the returned wrapper.
- * Invoked with (...args, callback).
- * @returns {AsyncFunction} The wrapped function, which when invoked, will
- * retry on an error, based on the parameters specified in `opts`.
- * This function will accept the same parameters as `task`.
- * @example
- *
- * async.auto({
- * dep1: async.retryable(3, getFromFlakyService),
- * process: ["dep1", async.retryable(3, function (results, cb) {
- * maybeProcessData(results.dep1, cb);
- * })]
- * }, callback);
- */
-var retryable = function (opts, task) {
- if (!task) {
- task = opts;
- opts = null;
+ function _times(mapper) {
+ return function (count, iterator, callback) {
+ mapper(_range(count), iterator, callback);
+ };
}
- var _task = wrapAsync(task);
- return initialParams(function (args, callback) {
- function taskFn(cb) {
- _task.apply(null, args.concat(cb));
- }
- if (opts) retry(opts, taskFn, callback);
- else retry(taskFn, callback);
-
- });
-};
-
-/**
- * Run the functions in the `tasks` collection in series, each one running once
- * the previous function has completed. If any functions in the series pass an
- * error to its callback, no more functions are run, and `callback` is
- * immediately called with the value of the error. Otherwise, `callback`
- * receives an array of results when `tasks` have completed.
- *
- * It is also possible to use an object instead of an array. Each property will
- * be run as a function, and the results will be passed to the final `callback`
- * as an object instead of an array. This can be a more readable way of handling
- * results from {@link async.series}.
- *
- * **Note** that while many implementations preserve the order of object
- * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
- * explicitly states that
- *
- * > The mechanics and order of enumerating the properties is not specified.
- *
- * So if you rely on the order in which your series of functions are executed,
- * and want this to work on all platforms, consider using an array.
- *
- * @name series
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Array|Iterable|Object} tasks - A collection containing
- * [async functions]{@link AsyncFunction} to run in series.
- * Each function can complete with any number of optional `result` values.
- * @param {Function} [callback] - An optional callback to run once all the
- * functions have completed. This function gets a results array (or object)
- * containing all the result arguments passed to the `task` callbacks. Invoked
- * with (err, result).
- * @example
- * async.series([
- * function(callback) {
- * // do some stuff ...
- * callback(null, 'one');
- * },
- * function(callback) {
- * // do some more stuff ...
- * callback(null, 'two');
- * }
- * ],
- * // optional callback
- * function(err, results) {
- * // results is now equal to ['one', 'two']
- * });
- *
- * async.series({
- * one: function(callback) {
- * setTimeout(function() {
- * callback(null, 1);
- * }, 200);
- * },
- * two: function(callback){
- * setTimeout(function() {
- * callback(null, 2);
- * }, 100);
- * }
- * }, function(err, results) {
- * // results is now equal to: {one: 1, two: 2}
- * });
- */
-function series(tasks, callback) {
- _parallel(eachOfSeries, tasks, callback);
-}
-
-/**
- * Returns `true` if at least one element in the `coll` satisfies an async test.
- * If any iteratee call returns `true`, the main `callback` is immediately
- * called.
- *
- * @name some
- * @static
- * @memberOf module:Collections
- * @method
- * @alias any
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async truth test to apply to each item
- * in the collections in parallel.
- * The iteratee should complete with a boolean `result` value.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called as soon as any
- * iteratee returns `true`, or after all the iteratee functions have finished.
- * Result will be either `true` or `false` depending on the values of the async
- * tests. Invoked with (err, result).
- * @example
- *
- * async.some(['file1','file2','file3'], function(filePath, callback) {
- * fs.access(filePath, function(err) {
- * callback(null, !err)
- * });
- * }, function(err, result) {
- * // if result is true then at least one of the files exists
- * });
- */
-var some = doParallel(_createTester(Boolean, identity));
+ async.times = _times(async.map);
+ async.timesSeries = _times(async.mapSeries);
+ async.timesLimit = function (count, limit, iterator, callback) {
+ return async.mapLimit(_range(count), limit, iterator, callback);
+ };
-/**
- * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
- *
- * @name someLimit
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.some]{@link module:Collections.some}
- * @alias anyLimit
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - An async truth test to apply to each item
- * in the collections in parallel.
- * The iteratee should complete with a boolean `result` value.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called as soon as any
- * iteratee returns `true`, or after all the iteratee functions have finished.
- * Result will be either `true` or `false` depending on the values of the async
- * tests. Invoked with (err, result).
- */
-var someLimit = doParallelLimit(_createTester(Boolean, identity));
+ async.seq = function (/* functions... */) {
+ var fns = arguments;
+ return _restParam(function (args) {
+ var that = this;
-/**
- * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
- *
- * @name someSeries
- * @static
- * @memberOf module:Collections
- * @method
- * @see [async.some]{@link module:Collections.some}
- * @alias anySeries
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async truth test to apply to each item
- * in the collections in series.
- * The iteratee should complete with a boolean `result` value.
- * Invoked with (item, callback).
- * @param {Function} [callback] - A callback which is called as soon as any
- * iteratee returns `true`, or after all the iteratee functions have finished.
- * Result will be either `true` or `false` depending on the values of the async
- * tests. Invoked with (err, result).
- */
-var someSeries = doLimit(someLimit, 1);
+ var callback = args[args.length - 1];
+ if (typeof callback == 'function') {
+ args.pop();
+ } else {
+ callback = noop;
+ }
-/**
- * Sorts a list by the results of running each `coll` value through an async
- * `iteratee`.
- *
- * @name sortBy
- * @static
- * @memberOf module:Collections
- * @method
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {AsyncFunction} iteratee - An async function to apply to each item in
- * `coll`.
- * The iteratee should complete with a value to use as the sort criteria as
- * its `result`.
- * Invoked with (item, callback).
- * @param {Function} callback - A callback which is called after all the
- * `iteratee` functions have finished, or an error occurs. Results is the items
- * from the original `coll` sorted by the values returned by the `iteratee`
- * calls. Invoked with (err, results).
- * @example
- *
- * async.sortBy(['file1','file2','file3'], function(file, callback) {
- * fs.stat(file, function(err, stats) {
- * callback(err, stats.mtime);
- * });
- * }, function(err, results) {
- * // results is now the original array of files sorted by
- * // modified date
- * });
- *
- * // By modifying the callback parameter the
- * // sorting order can be influenced:
- *
- * // ascending order
- * async.sortBy([1,9,3,5], function(x, callback) {
- * callback(null, x);
- * }, function(err,result) {
- * // result callback
- * });
- *
- * // descending order
- * async.sortBy([1,9,3,5], function(x, callback) {
- * callback(null, x*-1); //<- x*-1 instead of x, turns the order around
- * }, function(err,result) {
- * // result callback
- * });
- */
-function sortBy (coll, iteratee, callback) {
- var _iteratee = wrapAsync(iteratee);
- map(coll, function (x, callback) {
- _iteratee(x, function (err, criteria) {
- if (err) return callback(err);
- callback(null, {value: x, criteria: criteria});
+ async.reduce(fns, args, function (newargs, fn, cb) {
+ fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {
+ cb(err, nextargs);
+ })]));
+ },
+ function (err, results) {
+ callback.apply(that, [err].concat(results));
+ });
});
- }, function (err, results) {
- if (err) return callback(err);
- callback(null, arrayMap(results.sort(comparator), baseProperty('value')));
- });
+ };
- function comparator(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }
-}
+ async.compose = function (/* functions... */) {
+ return async.seq.apply(null, Array.prototype.reverse.call(arguments));
+ };
-/**
- * Sets a time limit on an asynchronous function. If the function does not call
- * its callback within the specified milliseconds, it will be called with a
- * timeout error. The code property for the error object will be `'ETIMEDOUT'`.
- *
- * @name timeout
- * @static
- * @memberOf module:Utils
- * @method
- * @category Util
- * @param {AsyncFunction} asyncFn - The async function to limit in time.
- * @param {number} milliseconds - The specified time limit.
- * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
- * to timeout Error for more information..
- * @returns {AsyncFunction} Returns a wrapped function that can be used with any
- * of the control flow functions.
- * Invoke this function with the same parameters as you would `asyncFunc`.
- * @example
- *
- * function myFunction(foo, callback) {
- * doAsyncTask(foo, function(err, data) {
- * // handle errors
- * if (err) return callback(err);
- *
- * // do some stuff ...
- *
- * // return processed data
- * return callback(null, data);
- * });
- * }
- *
- * var wrapped = async.timeout(myFunction, 1000);
- *
- * // call `wrapped` as you would `myFunction`
- * wrapped({ bar: 'bar' }, function(err, data) {
- * // if `myFunction` takes < 1000 ms to execute, `err`
- * // and `data` will have their expected values
- *
- * // else `err` will be an Error with the code 'ETIMEDOUT'
- * });
- */
-function timeout(asyncFn, milliseconds, info) {
- var fn = wrapAsync(asyncFn);
-
- return initialParams(function (args, callback) {
- var timedOut = false;
- var timer;
-
- function timeoutCallback() {
- var name = asyncFn.name || 'anonymous';
- var error = new Error('Callback function "' + name + '" timed out.');
- error.code = 'ETIMEDOUT';
- if (info) {
- error.info = info;
- }
- timedOut = true;
- callback(error);
- }
- args.push(function () {
- if (!timedOut) {
- callback.apply(null, arguments);
- clearTimeout(timer);
+ function _applyEach(eachfn) {
+ return _restParam(function(fns, args) {
+ var go = _restParam(function(args) {
+ var that = this;
+ var callback = args.pop();
+ return eachfn(fns, function (fn, _, cb) {
+ fn.apply(that, args.concat([cb]));
+ },
+ callback);
+ });
+ if (args.length) {
+ return go.apply(this, args);
+ }
+ else {
+ return go;
}
});
+ }
- // setup timer and call original function
- timer = setTimeout(timeoutCallback, milliseconds);
- fn.apply(null, args);
- });
-}
+ async.applyEach = _applyEach(async.eachOf);
+ async.applyEachSeries = _applyEach(async.eachOfSeries);
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeCeil = Math.ceil;
-var nativeMax = Math.max;
-/**
- * The base implementation of `_.range` and `_.rangeRight` which doesn't
- * coerce arguments.
- *
- * @private
- * @param {number} start The start of the range.
- * @param {number} end The end of the range.
- * @param {number} step The value to increment or decrement by.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Array} Returns the range of numbers.
- */
-function baseRange(start, end, step, fromRight) {
- var index = -1,
- length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
- result = Array(length);
-
- while (length--) {
- result[fromRight ? length : ++index] = start;
- start += step;
- }
- return result;
-}
-
-/**
- * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
- * time.
- *
- * @name timesLimit
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.times]{@link module:ControlFlow.times}
- * @category Control Flow
- * @param {number} count - The number of times to run the function.
- * @param {number} limit - The maximum number of async operations at a time.
- * @param {AsyncFunction} iteratee - The async function to call `n` times.
- * Invoked with the iteration index and a callback: (n, next).
- * @param {Function} callback - see [async.map]{@link module:Collections.map}.
- */
-function timeLimit(count, limit, iteratee, callback) {
- var _iteratee = wrapAsync(iteratee);
- mapLimit(baseRange(0, count, 1), limit, _iteratee, callback);
-}
-
-/**
- * Calls the `iteratee` function `n` times, and accumulates results in the same
- * manner you would use with [map]{@link module:Collections.map}.
- *
- * @name times
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.map]{@link module:Collections.map}
- * @category Control Flow
- * @param {number} n - The number of times to run the function.
- * @param {AsyncFunction} iteratee - The async function to call `n` times.
- * Invoked with the iteration index and a callback: (n, next).
- * @param {Function} callback - see {@link module:Collections.map}.
- * @example
- *
- * // Pretend this is some complicated async factory
- * var createUser = function(id, callback) {
- * callback(null, {
- * id: 'user' + id
- * });
- * };
- *
- * // generate 5 users
- * async.times(5, function(n, next) {
- * createUser(n, function(err, user) {
- * next(err, user);
- * });
- * }, function(err, users) {
- * // we should now have 5 users
- * });
- */
-var times = doLimit(timeLimit, Infinity);
-
-/**
- * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.
- *
- * @name timesSeries
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.times]{@link module:ControlFlow.times}
- * @category Control Flow
- * @param {number} n - The number of times to run the function.
- * @param {AsyncFunction} iteratee - The async function to call `n` times.
- * Invoked with the iteration index and a callback: (n, next).
- * @param {Function} callback - see {@link module:Collections.map}.
- */
-var timesSeries = doLimit(timeLimit, 1);
+ async.forever = function (fn, callback) {
+ var done = only_once(callback || noop);
+ var task = ensureAsync(fn);
+ function next(err) {
+ if (err) {
+ return done(err);
+ }
+ task(next);
+ }
+ next();
+ };
-/**
- * A relative of `reduce`. Takes an Object or Array, and iterates over each
- * element in series, each step potentially mutating an `accumulator` value.
- * The type of the accumulator defaults to the type of collection passed in.
- *
- * @name transform
- * @static
- * @memberOf module:Collections
- * @method
- * @category Collection
- * @param {Array|Iterable|Object} coll - A collection to iterate over.
- * @param {*} [accumulator] - The initial state of the transform. If omitted,
- * it will default to an empty Object or Array, depending on the type of `coll`
- * @param {AsyncFunction} iteratee - A function applied to each item in the
- * collection that potentially modifies the accumulator.
- * Invoked with (accumulator, item, key, callback).
- * @param {Function} [callback] - A callback which is called after all the
- * `iteratee` functions have finished. Result is the transformed accumulator.
- * Invoked with (err, result).
- * @example
- *
- * async.transform([1,2,3], function(acc, item, index, callback) {
- * // pointless async:
- * process.nextTick(function() {
- * acc.push(item * 2)
- * callback(null)
- * });
- * }, function(err, result) {
- * // result is now equal to [2, 4, 6]
- * });
- *
- * @example
- *
- * async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) {
- * setImmediate(function () {
- * obj[key] = val * 2;
- * callback();
- * })
- * }, function (err, result) {
- * // result is equal to {a: 2, b: 4, c: 6}
- * })
- */
-function transform (coll, accumulator, iteratee, callback) {
- if (arguments.length <= 3) {
- callback = iteratee;
- iteratee = accumulator;
- accumulator = isArray(coll) ? [] : {};
+ function ensureAsync(fn) {
+ return _restParam(function (args) {
+ var callback = args.pop();
+ args.push(function () {
+ var innerArgs = arguments;
+ if (sync) {
+ async.setImmediate(function () {
+ callback.apply(null, innerArgs);
+ });
+ } else {
+ callback.apply(null, innerArgs);
+ }
+ });
+ var sync = true;
+ fn.apply(this, args);
+ sync = false;
+ });
}
- callback = once(callback || noop);
- var _iteratee = wrapAsync(iteratee);
- eachOf(coll, function(v, k, cb) {
- _iteratee(accumulator, v, k, cb);
- }, function(err) {
- callback(err, accumulator);
+ async.ensureAsync = ensureAsync;
+
+ async.constant = _restParam(function(values) {
+ var args = [null].concat(values);
+ return function (callback) {
+ return callback.apply(this, args);
+ };
});
-}
-/**
- * It runs each task in series but stops whenever any of the functions were
- * successful. If one of the tasks were successful, the `callback` will be
- * passed the result of the successful task. If all tasks fail, the callback
- * will be passed the error and result (if any) of the final attempt.
- *
- * @name tryEach
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Array|Iterable|Object} tasks - A collection containing functions to
- * run, each function is passed a `callback(err, result)` it must call on
- * completion with an error `err` (which can be `null`) and an optional `result`
- * value.
- * @param {Function} [callback] - An optional callback which is called when one
- * of the tasks has succeeded, or all have failed. It receives the `err` and
- * `result` arguments of the last attempt at completing the `task`. Invoked with
- * (err, results).
- * @example
- * async.try([
- * function getDataFromFirstWebsite(callback) {
- * // Try getting the data from the first website
- * callback(err, data);
- * },
- * function getDataFromSecondWebsite(callback) {
- * // First website failed,
- * // Try getting the data from the backup website
- * callback(err, data);
- * }
- * ],
- * // optional callback
- * function(err, results) {
- * Now do something with the data.
- * });
- *
- */
-function tryEach(tasks, callback) {
- var error = null;
- var result;
- callback = callback || noop;
- eachSeries(tasks, function(task, callback) {
- wrapAsync(task)(function (err, res/*, ...args*/) {
- if (arguments.length > 2) {
- result = slice(arguments, 1);
+ async.wrapSync =
+ async.asyncify = function asyncify(func) {
+ return _restParam(function (args) {
+ var callback = args.pop();
+ var result;
+ try {
+ result = func.apply(this, args);
+ } catch (e) {
+ return callback(e);
+ }
+ // if result is Promise object
+ if (_isObject(result) && typeof result.then === "function") {
+ result.then(function(value) {
+ callback(null, value);
+ })["catch"](function(err) {
+ callback(err.message ? err : new Error(err));
+ });
} else {
- result = res;
+ callback(null, result);
}
- error = err;
- callback(!err);
});
- }, function () {
- callback(error, result);
- });
-}
-
-/**
- * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,
- * unmemoized form. Handy for testing.
- *
- * @name unmemoize
- * @static
- * @memberOf module:Utils
- * @method
- * @see [async.memoize]{@link module:Utils.memoize}
- * @category Util
- * @param {AsyncFunction} fn - the memoized function
- * @returns {AsyncFunction} a function that calls the original unmemoized function
- */
-function unmemoize(fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
};
-}
-/**
- * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
- * stopped, or an error occurs.
- *
- * @name whilst
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Function} test - synchronous truth test to perform before each
- * execution of `iteratee`. Invoked with ().
- * @param {AsyncFunction} iteratee - An async function which is called each time
- * `test` passes. Invoked with (callback).
- * @param {Function} [callback] - A callback which is called after the test
- * function has failed and repeated execution of `iteratee` has stopped. `callback`
- * will be passed an error and any arguments passed to the final `iteratee`'s
- * callback. Invoked with (err, [results]);
- * @returns undefined
- * @example
- *
- * var count = 0;
- * async.whilst(
- * function() { return count < 5; },
- * function(callback) {
- * count++;
- * setTimeout(function() {
- * callback(null, count);
- * }, 1000);
- * },
- * function (err, n) {
- * // 5 seconds have passed, n = 5
- * }
- * );
- */
-function whilst(test, iteratee, callback) {
- callback = onlyOnce(callback || noop);
- var _iteratee = wrapAsync(iteratee);
- if (!test()) return callback(null);
- var next = function(err/*, ...args*/) {
- if (err) return callback(err);
- if (test()) return _iteratee(next);
- var args = slice(arguments, 1);
- callback.apply(null, [null].concat(args));
- };
- _iteratee(next);
-}
-
-/**
- * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
- * stopped, or an error occurs. `callback` will be passed an error and any
- * arguments passed to the final `iteratee`'s callback.
- *
- * The inverse of [whilst]{@link module:ControlFlow.whilst}.
- *
- * @name until
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @see [async.whilst]{@link module:ControlFlow.whilst}
- * @category Control Flow
- * @param {Function} test - synchronous truth test to perform before each
- * execution of `iteratee`. Invoked with ().
- * @param {AsyncFunction} iteratee - An async function which is called each time
- * `test` fails. Invoked with (callback).
- * @param {Function} [callback] - A callback which is called after the test
- * function has passed and repeated execution of `iteratee` has stopped. `callback`
- * will be passed an error and any arguments passed to the final `iteratee`'s
- * callback. Invoked with (err, [results]);
- */
-function until(test, iteratee, callback) {
- whilst(function() {
- return !test.apply(this, arguments);
- }, iteratee, callback);
-}
-
-/**
- * Runs the `tasks` array of functions in series, each passing their results to
- * the next in the array. However, if any of the `tasks` pass an error to their
- * own callback, the next function is not executed, and the main `callback` is
- * immediately called with the error.
- *
- * @name waterfall
- * @static
- * @memberOf module:ControlFlow
- * @method
- * @category Control Flow
- * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
- * to run.
- * Each function should complete with any number of `result` values.
- * The `result` values will be passed as arguments, in order, to the next task.
- * @param {Function} [callback] - An optional callback to run once all the
- * functions have completed. This will be passed the results of the last task's
- * callback. Invoked with (err, [results]).
- * @returns undefined
- * @example
- *
- * async.waterfall([
- * function(callback) {
- * callback(null, 'one', 'two');
- * },
- * function(arg1, arg2, callback) {
- * // arg1 now equals 'one' and arg2 now equals 'two'
- * callback(null, 'three');
- * },
- * function(arg1, callback) {
- * // arg1 now equals 'three'
- * callback(null, 'done');
- * }
- * ], function (err, result) {
- * // result now equals 'done'
- * });
- *
- * // Or, with named functions:
- * async.waterfall([
- * myFirstFunction,
- * mySecondFunction,
- * myLastFunction,
- * ], function (err, result) {
- * // result now equals 'done'
- * });
- * function myFirstFunction(callback) {
- * callback(null, 'one', 'two');
- * }
- * function mySecondFunction(arg1, arg2, callback) {
- * // arg1 now equals 'one' and arg2 now equals 'two'
- * callback(null, 'three');
- * }
- * function myLastFunction(arg1, callback) {
- * // arg1 now equals 'three'
- * callback(null, 'done');
- * }
- */
-var waterfall = function(tasks, callback) {
- callback = once(callback || noop);
- if (!isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
- if (!tasks.length) return callback();
- var taskIndex = 0;
-
- function nextTask(args) {
- var task = wrapAsync(tasks[taskIndex++]);
- args.push(onlyOnce(next));
- task.apply(null, args);
+ // Node.js
+ if (typeof module === 'object' && module.exports) {
+ module.exports = async;
}
-
- function next(err/*, ...args*/) {
- if (err || taskIndex === tasks.length) {
- return callback.apply(null, arguments);
- }
- nextTask(slice(arguments, 1));
+ // AMD / RequireJS
+ else if (typeof define === 'function' && define.amd) {
+ define([], function () {
+ return async;
+ });
+ }
+ // included directly via <script> tag
+ else {
+ root.async = async;
}
- nextTask([]);
-};
-
-/**
- * An "async function" in the context of Async is an asynchronous function with
- * a variable number of parameters, with the final parameter being a callback.
- * (`function (arg1, arg2, ..., callback) {}`)
- * The final callback is of the form `callback(err, results...)`, which must be
- * called once the function is completed. The callback should be called with a
- * Error as its first argument to signal that an error occurred.
- * Otherwise, if no error occurred, it should be called with `null` as the first
- * argument, and any additional `result` arguments that may apply, to signal
- * successful completion.
- * The callback must be called exactly once, ideally on a later tick of the
- * JavaScript event loop.
- *
- * This type of function is also referred to as a "Node-style async function",
- * or a "continuation passing-style function" (CPS). Most of the methods of this
- * library are themselves CPS/Node-style async functions, or functions that
- * return CPS/Node-style async functions.
- *
- * Wherever we accept a Node-style async function, we also directly accept an
- * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
- * In this case, the `async` function will not be passed a final callback
- * argument, and any thrown error will be used as the `err` argument of the
- * implicit callback, and the return value will be used as the `result` value.
- * (i.e. a `rejected` of the returned Promise becomes the `err` callback
- * argument, and a `resolved` value becomes the `result`.)
- *
- * Note, due to JavaScript limitations, we can only detect native `async`
- * functions and not transpilied implementations.
- * Your environment must have `async`/`await` support for this to work.
- * (e.g. Node > v7.6, or a recent version of a modern browser).
- * If you are using `async` functions through a transpiler (e.g. Babel), you
- * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
- * because the `async function` will be compiled to an ordinary function that
- * returns a promise.
- *
- * @typedef {Function} AsyncFunction
- * @static
- */
-
-/**
- * Async is a utility module which provides straight-forward, powerful functions
- * for working with asynchronous JavaScript. Although originally designed for
- * use with [Node.js](http://nodejs.org) and installable via
- * `npm install --save async`, it can also be used directly in the browser.
- * @module async
- * @see AsyncFunction
- */
-
-
-/**
- * A collection of `async` functions for manipulating collections, such as
- * arrays and objects.
- * @module Collections
- */
-
-/**
- * A collection of `async` functions for controlling the flow through a script.
- * @module ControlFlow
- */
-
-/**
- * A collection of `async` utility functions.
- * @module Utils
- */
-
-var index = {
- applyEach: applyEach,
- applyEachSeries: applyEachSeries,
- apply: apply,
- asyncify: asyncify,
- auto: auto,
- autoInject: autoInject,
- cargo: cargo,
- compose: compose,
- concat: concat,
- concatLimit: concatLimit,
- concatSeries: concatSeries,
- constant: constant,
- detect: detect,
- detectLimit: detectLimit,
- detectSeries: detectSeries,
- dir: dir,
- doDuring: doDuring,
- doUntil: doUntil,
- doWhilst: doWhilst,
- during: during,
- each: eachLimit,
- eachLimit: eachLimit$1,
- eachOf: eachOf,
- eachOfLimit: eachOfLimit,
- eachOfSeries: eachOfSeries,
- eachSeries: eachSeries,
- ensureAsync: ensureAsync,
- every: every,
- everyLimit: everyLimit,
- everySeries: everySeries,
- filter: filter,
- filterLimit: filterLimit,
- filterSeries: filterSeries,
- forever: forever,
- groupBy: groupBy,
- groupByLimit: groupByLimit,
- groupBySeries: groupBySeries,
- log: log,
- map: map,
- mapLimit: mapLimit,
- mapSeries: mapSeries,
- mapValues: mapValues,
- mapValuesLimit: mapValuesLimit,
- mapValuesSeries: mapValuesSeries,
- memoize: memoize,
- nextTick: nextTick,
- parallel: parallelLimit,
- parallelLimit: parallelLimit$1,
- priorityQueue: priorityQueue,
- queue: queue$1,
- race: race,
- reduce: reduce,
- reduceRight: reduceRight,
- reflect: reflect,
- reflectAll: reflectAll,
- reject: reject,
- rejectLimit: rejectLimit,
- rejectSeries: rejectSeries,
- retry: retry,
- retryable: retryable,
- seq: seq,
- series: series,
- setImmediate: setImmediate$1,
- some: some,
- someLimit: someLimit,
- someSeries: someSeries,
- sortBy: sortBy,
- timeout: timeout,
- times: times,
- timesLimit: timeLimit,
- timesSeries: timesSeries,
- transform: transform,
- tryEach: tryEach,
- unmemoize: unmemoize,
- until: until,
- waterfall: waterfall,
- whilst: whilst,
-
- // aliases
- all: every,
- any: some,
- forEach: eachLimit,
- forEachSeries: eachSeries,
- forEachLimit: eachLimit$1,
- forEachOf: eachOf,
- forEachOfSeries: eachOfSeries,
- forEachOfLimit: eachOfLimit,
- inject: reduce,
- foldl: reduce,
- foldr: reduceRight,
- select: filter,
- selectLimit: filterLimit,
- selectSeries: filterSeries,
- wrapSync: asyncify
-};
-
-exports['default'] = index;
-exports.applyEach = applyEach;
-exports.applyEachSeries = applyEachSeries;
-exports.apply = apply;
-exports.asyncify = asyncify;
-exports.auto = auto;
-exports.autoInject = autoInject;
-exports.cargo = cargo;
-exports.compose = compose;
-exports.concat = concat;
-exports.concatLimit = concatLimit;
-exports.concatSeries = concatSeries;
-exports.constant = constant;
-exports.detect = detect;
-exports.detectLimit = detectLimit;
-exports.detectSeries = detectSeries;
-exports.dir = dir;
-exports.doDuring = doDuring;
-exports.doUntil = doUntil;
-exports.doWhilst = doWhilst;
-exports.during = during;
-exports.each = eachLimit;
-exports.eachLimit = eachLimit$1;
-exports.eachOf = eachOf;
-exports.eachOfLimit = eachOfLimit;
-exports.eachOfSeries = eachOfSeries;
-exports.eachSeries = eachSeries;
-exports.ensureAsync = ensureAsync;
-exports.every = every;
-exports.everyLimit = everyLimit;
-exports.everySeries = everySeries;
-exports.filter = filter;
-exports.filterLimit = filterLimit;
-exports.filterSeries = filterSeries;
-exports.forever = forever;
-exports.groupBy = groupBy;
-exports.groupByLimit = groupByLimit;
-exports.groupBySeries = groupBySeries;
-exports.log = log;
-exports.map = map;
-exports.mapLimit = mapLimit;
-exports.mapSeries = mapSeries;
-exports.mapValues = mapValues;
-exports.mapValuesLimit = mapValuesLimit;
-exports.mapValuesSeries = mapValuesSeries;
-exports.memoize = memoize;
-exports.nextTick = nextTick;
-exports.parallel = parallelLimit;
-exports.parallelLimit = parallelLimit$1;
-exports.priorityQueue = priorityQueue;
-exports.queue = queue$1;
-exports.race = race;
-exports.reduce = reduce;
-exports.reduceRight = reduceRight;
-exports.reflect = reflect;
-exports.reflectAll = reflectAll;
-exports.reject = reject;
-exports.rejectLimit = rejectLimit;
-exports.rejectSeries = rejectSeries;
-exports.retry = retry;
-exports.retryable = retryable;
-exports.seq = seq;
-exports.series = series;
-exports.setImmediate = setImmediate$1;
-exports.some = some;
-exports.someLimit = someLimit;
-exports.someSeries = someSeries;
-exports.sortBy = sortBy;
-exports.timeout = timeout;
-exports.times = times;
-exports.timesLimit = timeLimit;
-exports.timesSeries = timesSeries;
-exports.transform = transform;
-exports.tryEach = tryEach;
-exports.unmemoize = unmemoize;
-exports.until = until;
-exports.waterfall = waterfall;
-exports.whilst = whilst;
-exports.all = every;
-exports.allLimit = everyLimit;
-exports.allSeries = everySeries;
-exports.any = some;
-exports.anyLimit = someLimit;
-exports.anySeries = someSeries;
-exports.find = detect;
-exports.findLimit = detectLimit;
-exports.findSeries = detectSeries;
-exports.forEach = eachLimit;
-exports.forEachSeries = eachSeries;
-exports.forEachLimit = eachLimit$1;
-exports.forEachOf = eachOf;
-exports.forEachOfSeries = eachOfSeries;
-exports.forEachOfLimit = eachOfLimit;
-exports.inject = reduce;
-exports.foldl = reduce;
-exports.foldr = reduceRight;
-exports.select = filter;
-exports.selectLimit = filterLimit;
-exports.selectSeries = filterSeries;
-exports.wrapSync = asyncify;
-
-Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
+}());
diff --git a/node_modules/async/dist/async.min.js b/node_modules/async/dist/async.min.js
index 364629992..2490016a0 100644
--- a/node_modules/async/dist/async.min.js
+++ b/node_modules/async/dist/async.min.js
@@ -1,2 +1,2 @@
-!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.async=n.async||{})}(this,function(n){"use strict";function t(n,t){t|=0;for(var e=Math.max(n.length-t,0),r=Array(e),u=0;u<e;u++)r[u]=n[t+u];return r}function e(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function r(n){setTimeout(n,0)}function u(n){return function(e){var r=t(arguments,1);n(function(){e.apply(null,r)})}}function o(n){return it(function(t,r){var u;try{u=n.apply(this,t)}catch(n){return r(n)}e(u)&&"function"==typeof u.then?u.then(function(n){i(r,null,n)},function(n){i(r,n.message?n:new Error(n))}):r(null,u)})}function i(n,t,e){try{n(t,e)}catch(n){at(c,n)}}function c(n){throw n}function f(n){return lt&&"AsyncFunction"===n[Symbol.toStringTag]}function a(n){return f(n)?o(n):n}function l(n){return function(e){var r=t(arguments,1),u=it(function(t,r){var u=this;return n(e,function(n,e){a(n).apply(u,t.concat(e))},r)});return r.length?u.apply(this,r):u}}function s(n){var t=dt.call(n,gt),e=n[gt];try{n[gt]=void 0;var r=!0}catch(n){}var u=mt.call(n);return r&&(t?n[gt]=e:delete n[gt]),u}function p(n){return jt.call(n)}function h(n){return null==n?void 0===n?kt:St:(n=Object(n),Lt&&Lt in n?s(n):p(n))}function y(n){if(!e(n))return!1;var t=h(n);return t==wt||t==xt||t==Ot||t==Et}function v(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=At}function d(n){return null!=n&&v(n.length)&&!y(n)}function m(){}function g(n){return function(){if(null!==n){var t=n;n=null,t.apply(this,arguments)}}}function b(n,t){for(var e=-1,r=Array(n);++e<n;)r[e]=t(e);return r}function j(n){return null!=n&&"object"==typeof n}function S(n){return j(n)&&h(n)==It}function k(){return!1}function L(n,t){return t=null==t?Wt:t,!!t&&("number"==typeof n||Nt.test(n))&&n>-1&&n%1==0&&n<t}function O(n){return j(n)&&v(n.length)&&!!de[h(n)]}function w(n){return function(t){return n(t)}}function x(n,t){var e=Pt(n),r=!e&&zt(n),u=!e&&!r&&$t(n),o=!e&&!r&&!u&&Le(n),i=e||r||u||o,c=i?b(n.length,String):[],f=c.length;for(var a in n)!t&&!we.call(n,a)||i&&("length"==a||u&&("offset"==a||"parent"==a)||o&&("buffer"==a||"byteLength"==a||"byteOffset"==a)||L(a,f))||c.push(a);return c}function E(n){var t=n&&n.constructor,e="function"==typeof t&&t.prototype||xe;return n===e}function A(n,t){return function(e){return n(t(e))}}function T(n){if(!E(n))return Ee(n);var t=[];for(var e in Object(n))Te.call(n,e)&&"constructor"!=e&&t.push(e);return t}function B(n){return d(n)?x(n):T(n)}function F(n){var t=-1,e=n.length;return function(){return++t<e?{value:n[t],key:t}:null}}function I(n){var t=-1;return function(){var e=n.next();return e.done?null:(t++,{value:e.value,key:t})}}function _(n){var t=B(n),e=-1,r=t.length;return function(){var u=t[++e];return e<r?{value:n[u],key:u}:null}}function M(n){if(d(n))return F(n);var t=Ft(n);return t?I(t):_(n)}function U(n){return function(){if(null===n)throw new Error("Callback was already called.");var t=n;n=null,t.apply(this,arguments)}}function z(n){return function(t,e,r){function u(n,t){if(f-=1,n)c=!0,r(n);else{if(t===Tt||c&&f<=0)return c=!0,r(null);o()}}function o(){for(;f<n&&!c;){var t=i();if(null===t)return c=!0,void(f<=0&&r(null));f+=1,e(t.value,t.key,U(u))}}if(r=g(r||m),n<=0||!t)return r(null);var i=M(t),c=!1,f=0;o()}}function P(n,t,e,r){z(t)(n,a(e),r)}function V(n,t){return function(e,r,u){return n(e,t,r,u)}}function q(n,t,e){function r(n,t){n?e(n):++o!==i&&t!==Tt||e(null)}e=g(e||m);var u=0,o=0,i=n.length;for(0===i&&e(null);u<i;u++)t(n[u],u,U(r))}function D(n){return function(t,e,r){return n(Fe,t,a(e),r)}}function R(n,t,e,r){r=r||m,t=t||[];var u=[],o=0,i=a(e);n(t,function(n,t,e){var r=o++;i(n,function(n,t){u[r]=t,e(n)})},function(n){r(n,u)})}function C(n){return function(t,e,r,u){return n(z(e),t,a(r),u)}}function $(n,t){for(var e=-1,r=null==n?0:n.length;++e<r&&t(n[e],e,n)!==!1;);return n}function W(n){return function(t,e,r){for(var u=-1,o=Object(t),i=r(t),c=i.length;c--;){var f=i[n?c:++u];if(e(o[f],f,o)===!1)break}return t}}function N(n,t){return n&&Ve(n,t,B)}function Q(n,t,e,r){for(var u=n.length,o=e+(r?1:-1);r?o--:++o<u;)if(t(n[o],o,n))return o;return-1}function G(n){return n!==n}function H(n,t,e){for(var r=e-1,u=n.length;++r<u;)if(n[r]===t)return r;return-1}function J(n,t,e){return t===t?H(n,t,e):Q(n,G,e)}function K(n,t){for(var e=-1,r=null==n?0:n.length,u=Array(r);++e<r;)u[e]=t(n[e],e,n);return u}function X(n){return"symbol"==typeof n||j(n)&&h(n)==De}function Y(n){if("string"==typeof n)return n;if(Pt(n))return K(n,Y)+"";if(X(n))return $e?$e.call(n):"";var t=n+"";return"0"==t&&1/n==-Re?"-0":t}function Z(n,t,e){var r=-1,u=n.length;t<0&&(t=-t>u?0:u+t),e=e>u?u:e,e<0&&(e+=u),u=t>e?0:e-t>>>0,t>>>=0;for(var o=Array(u);++r<u;)o[r]=n[r+t];return o}function nn(n,t,e){var r=n.length;return e=void 0===e?r:e,!t&&e>=r?n:Z(n,t,e)}function tn(n,t){for(var e=n.length;e--&&J(t,n[e],0)>-1;);return e}function en(n,t){for(var e=-1,r=n.length;++e<r&&J(t,n[e],0)>-1;);return e}function rn(n){return n.split("")}function un(n){return Je.test(n)}function on(n){return n.match(hr)||[]}function cn(n){return un(n)?on(n):rn(n)}function fn(n){return null==n?"":Y(n)}function an(n,t,e){if(n=fn(n),n&&(e||void 0===t))return n.replace(yr,"");if(!n||!(t=Y(t)))return n;var r=cn(n),u=cn(t),o=en(r,u),i=tn(r,u)+1;return nn(r,o,i).join("")}function ln(n){return n=n.toString().replace(gr,""),n=n.match(vr)[2].replace(" ",""),n=n?n.split(dr):[],n=n.map(function(n){return an(n.replace(mr,""))})}function sn(n,t){var e={};N(n,function(n,t){function r(t,e){var r=K(u,function(n){return t[n]});r.push(e),a(n).apply(null,r)}var u,o=f(n),i=!o&&1===n.length||o&&0===n.length;if(Pt(n))u=n.slice(0,-1),n=n[n.length-1],e[t]=u.concat(u.length>0?r:n);else if(i)e[t]=n;else{if(u=ln(n),0===n.length&&!o&&0===u.length)throw new Error("autoInject task functions require explicit parameters.");o||u.pop(),e[t]=u.concat(r)}}),qe(e,t)}function pn(){this.head=this.tail=null,this.length=0}function hn(n,t){n.length=1,n.head=n.tail=t}function yn(n,t,e){function r(n,t,e){if(null!=e&&"function"!=typeof e)throw new Error("task callback must be a function");if(l.started=!0,Pt(n)||(n=[n]),0===n.length&&l.idle())return at(function(){l.drain()});for(var r=0,u=n.length;r<u;r++){var o={data:n[r],callback:e||m};t?l._tasks.unshift(o):l._tasks.push(o)}at(l.process)}function u(n){return function(t){i-=1;for(var e=0,r=n.length;e<r;e++){var u=n[e],o=J(c,u,0);o>=0&&c.splice(o,1),u.callback.apply(u,arguments),null!=t&&l.error(t,u.data)}i<=l.concurrency-l.buffer&&l.unsaturated(),l.idle()&&l.drain(),l.process()}}if(null==t)t=1;else if(0===t)throw new Error("Concurrency must not be zero");var o=a(n),i=0,c=[],f=!1,l={_tasks:new pn,concurrency:t,payload:e,saturated:m,unsaturated:m,buffer:t/4,empty:m,drain:m,error:m,started:!1,paused:!1,push:function(n,t){r(n,!1,t)},kill:function(){l.drain=m,l._tasks.empty()},unshift:function(n,t){r(n,!0,t)},remove:function(n){l._tasks.remove(n)},process:function(){if(!f){for(f=!0;!l.paused&&i<l.concurrency&&l._tasks.length;){var n=[],t=[],e=l._tasks.length;l.payload&&(e=Math.min(e,l.payload));for(var r=0;r<e;r++){var a=l._tasks.shift();n.push(a),c.push(a),t.push(a.data)}i+=1,0===l._tasks.length&&l.empty(),i===l.concurrency&&l.saturated();var s=U(u(n));o(t,s)}f=!1}},length:function(){return l._tasks.length},running:function(){return i},workersList:function(){return c},idle:function(){return l._tasks.length+i===0},pause:function(){l.paused=!0},resume:function(){l.paused!==!1&&(l.paused=!1,at(l.process))}};return l}function vn(n,t){return yn(n,1,t)}function dn(n,t,e,r){r=g(r||m);var u=a(e);jr(n,function(n,e,r){u(t,n,function(n,e){t=e,r(n)})},function(n){r(n,t)})}function mn(){var n=K(arguments,a);return function(){var e=t(arguments),r=this,u=e[e.length-1];"function"==typeof u?e.pop():u=m,dn(n,e,function(n,e,u){e.apply(r,n.concat(function(n){var e=t(arguments,1);u(n,e)}))},function(n,t){u.apply(r,[n].concat(t))})}}function gn(n){return n}function bn(n,t){return function(e,r,u,o){o=o||m;var i,c=!1;e(r,function(e,r,o){u(e,function(r,u){r?o(r):n(u)&&!i?(c=!0,i=t(!0,e),o(null,Tt)):o()})},function(n){n?o(n):o(null,c?i:t(!1))})}}function jn(n,t){return t}function Sn(n){return function(e){var r=t(arguments,1);r.push(function(e){var r=t(arguments,1);"object"==typeof console&&(e?console.error&&console.error(e):console[n]&&$(r,function(t){console[n](t)}))}),a(e).apply(null,r)}}function kn(n,e,r){function u(n){if(n)return r(n);var e=t(arguments,1);e.push(o),c.apply(this,e)}function o(n,t){return n?r(n):t?void i(u):r(null)}r=U(r||m);var i=a(n),c=a(e);o(null,!0)}function Ln(n,e,r){r=U(r||m);var u=a(n),o=function(n){if(n)return r(n);var i=t(arguments,1);return e.apply(this,i)?u(o):void r.apply(null,[null].concat(i))};u(o)}function On(n,t,e){Ln(n,function(){return!t.apply(this,arguments)},e)}function wn(n,t,e){function r(n){return n?e(n):void i(u)}function u(n,t){return n?e(n):t?void o(r):e(null)}e=U(e||m);var o=a(t),i=a(n);i(u)}function xn(n){return function(t,e,r){return n(t,r)}}function En(n,t,e){Fe(n,xn(a(t)),e)}function An(n,t,e,r){z(t)(n,xn(a(e)),r)}function Tn(n){return f(n)?n:it(function(t,e){var r=!0;t.push(function(){var n=arguments;r?at(function(){e.apply(null,n)}):e.apply(null,n)}),n.apply(this,t),r=!1})}function Bn(n){return!n}function Fn(n){return function(t){return null==t?void 0:t[n]}}function In(n,t,e,r){var u=new Array(t.length);n(t,function(n,t,r){e(n,function(n,e){u[t]=!!e,r(n)})},function(n){if(n)return r(n);for(var e=[],o=0;o<t.length;o++)u[o]&&e.push(t[o]);r(null,e)})}function _n(n,t,e,r){var u=[];n(t,function(n,t,r){e(n,function(e,o){e?r(e):(o&&u.push({index:t,value:n}),r())})},function(n){n?r(n):r(null,K(u.sort(function(n,t){return n.index-t.index}),Fn("value")))})}function Mn(n,t,e,r){var u=d(t)?In:_n;u(n,t,a(e),r||m)}function Un(n,t){function e(n){return n?r(n):void u(e)}var r=U(t||m),u=a(Tn(n));e()}function zn(n,t,e,r){r=g(r||m);var u={},o=a(e);P(n,t,function(n,t,e){o(n,t,function(n,r){return n?e(n):(u[t]=r,void e())})},function(n){r(n,u)})}function Pn(n,t){return t in n}function Vn(n,e){var r=Object.create(null),u=Object.create(null);e=e||gn;var o=a(n),i=it(function(n,i){var c=e.apply(null,n);Pn(r,c)?at(function(){i.apply(null,r[c])}):Pn(u,c)?u[c].push(i):(u[c]=[i],o.apply(null,n.concat(function(){var n=t(arguments);r[c]=n;var e=u[c];delete u[c];for(var o=0,i=e.length;o<i;o++)e[o].apply(null,n)})))});return i.memo=r,i.unmemoized=n,i}function qn(n,e,r){r=r||m;var u=d(e)?[]:{};n(e,function(n,e,r){a(n)(function(n,o){arguments.length>2&&(o=t(arguments,1)),u[e]=o,r(n)})},function(n){r(n,u)})}function Dn(n,t){qn(Fe,n,t)}function Rn(n,t,e){qn(z(t),n,e)}function Cn(n,t){if(t=g(t||m),!Pt(n))return t(new TypeError("First argument to race must be an array of functions"));if(!n.length)return t();for(var e=0,r=n.length;e<r;e++)a(n[e])(t)}function $n(n,e,r,u){var o=t(n).reverse();dn(o,e,r,u)}function Wn(n){var e=a(n);return it(function(n,r){return n.push(function(n,e){if(n)r(null,{error:n});else{var u;u=arguments.length<=2?e:t(arguments,1),r(null,{value:u})}}),e.apply(this,n)})}function Nn(n,t,e,r){Mn(n,t,function(n,t){e(n,function(n,e){t(n,!e)})},r)}function Qn(n){var t;return Pt(n)?t=K(n,Wn):(t={},N(n,function(n,e){t[e]=Wn.call(this,n)})),t}function Gn(n){return function(){return n}}function Hn(n,t,e){function r(n,t){if("object"==typeof t)n.times=+t.times||o,n.intervalFunc="function"==typeof t.interval?t.interval:Gn(+t.interval||i),n.errorFilter=t.errorFilter;else{if("number"!=typeof t&&"string"!=typeof t)throw new Error("Invalid arguments for async.retry");n.times=+t||o}}function u(){f(function(n){n&&l++<c.times&&("function"!=typeof c.errorFilter||c.errorFilter(n))?setTimeout(u,c.intervalFunc(l)):e.apply(null,arguments)})}var o=5,i=0,c={times:o,intervalFunc:Gn(i)};if(arguments.length<3&&"function"==typeof n?(e=t||m,t=n):(r(c,n),e=e||m),"function"!=typeof t)throw new Error("Invalid arguments for async.retry");var f=a(t),l=1;u()}function Jn(n,t){qn(jr,n,t)}function Kn(n,t,e){function r(n,t){var e=n.criteria,r=t.criteria;return e<r?-1:e>r?1:0}var u=a(t);Ie(n,function(n,t){u(n,function(e,r){return e?t(e):void t(null,{value:n,criteria:r})})},function(n,t){return n?e(n):void e(null,K(t.sort(r),Fn("value")))})}function Xn(n,t,e){var r=a(n);return it(function(u,o){function i(){var t=n.name||"anonymous",r=new Error('Callback function "'+t+'" timed out.');r.code="ETIMEDOUT",e&&(r.info=e),f=!0,o(r)}var c,f=!1;u.push(function(){f||(o.apply(null,arguments),clearTimeout(c))}),c=setTimeout(i,t),r.apply(null,u)})}function Yn(n,t,e,r){for(var u=-1,o=tu(nu((t-n)/(e||1)),0),i=Array(o);o--;)i[r?o:++u]=n,n+=e;return i}function Zn(n,t,e,r){var u=a(e);Me(Yn(0,n,1),t,u,r)}function nt(n,t,e,r){arguments.length<=3&&(r=e,e=t,t=Pt(n)?[]:{}),r=g(r||m);var u=a(e);Fe(n,function(n,e,r){u(t,n,e,r)},function(n){r(n,t)})}function tt(n,e){var r,u=null;e=e||m,Fr(n,function(n,e){a(n)(function(n,o){r=arguments.length>2?t(arguments,1):o,u=n,e(!n)})},function(){e(u,r)})}function et(n){return function(){return(n.unmemoized||n).apply(null,arguments)}}function rt(n,e,r){r=U(r||m);var u=a(e);if(!n())return r(null);var o=function(e){if(e)return r(e);if(n())return u(o);var i=t(arguments,1);r.apply(null,[null].concat(i))};u(o)}function ut(n,t,e){rt(function(){return!n.apply(this,arguments)},t,e)}var ot,it=function(n){return function(){var e=t(arguments),r=e.pop();n.call(this,e,r)}},ct="function"==typeof setImmediate&&setImmediate,ft="object"==typeof process&&"function"==typeof process.nextTick;ot=ct?setImmediate:ft?process.nextTick:r;var at=u(ot),lt="function"==typeof Symbol,st="object"==typeof global&&global&&global.Object===Object&&global,pt="object"==typeof self&&self&&self.Object===Object&&self,ht=st||pt||Function("return this")(),yt=ht.Symbol,vt=Object.prototype,dt=vt.hasOwnProperty,mt=vt.toString,gt=yt?yt.toStringTag:void 0,bt=Object.prototype,jt=bt.toString,St="[object Null]",kt="[object Undefined]",Lt=yt?yt.toStringTag:void 0,Ot="[object AsyncFunction]",wt="[object Function]",xt="[object GeneratorFunction]",Et="[object Proxy]",At=9007199254740991,Tt={},Bt="function"==typeof Symbol&&Symbol.iterator,Ft=function(n){return Bt&&n[Bt]&&n[Bt]()},It="[object Arguments]",_t=Object.prototype,Mt=_t.hasOwnProperty,Ut=_t.propertyIsEnumerable,zt=S(function(){return arguments}())?S:function(n){return j(n)&&Mt.call(n,"callee")&&!Ut.call(n,"callee")},Pt=Array.isArray,Vt="object"==typeof n&&n&&!n.nodeType&&n,qt=Vt&&"object"==typeof module&&module&&!module.nodeType&&module,Dt=qt&&qt.exports===Vt,Rt=Dt?ht.Buffer:void 0,Ct=Rt?Rt.isBuffer:void 0,$t=Ct||k,Wt=9007199254740991,Nt=/^(?:0|[1-9]\d*)$/,Qt="[object Arguments]",Gt="[object Array]",Ht="[object Boolean]",Jt="[object Date]",Kt="[object Error]",Xt="[object Function]",Yt="[object Map]",Zt="[object Number]",ne="[object Object]",te="[object RegExp]",ee="[object Set]",re="[object String]",ue="[object WeakMap]",oe="[object ArrayBuffer]",ie="[object DataView]",ce="[object Float32Array]",fe="[object Float64Array]",ae="[object Int8Array]",le="[object Int16Array]",se="[object Int32Array]",pe="[object Uint8Array]",he="[object Uint8ClampedArray]",ye="[object Uint16Array]",ve="[object Uint32Array]",de={};de[ce]=de[fe]=de[ae]=de[le]=de[se]=de[pe]=de[he]=de[ye]=de[ve]=!0,de[Qt]=de[Gt]=de[oe]=de[Ht]=de[ie]=de[Jt]=de[Kt]=de[Xt]=de[Yt]=de[Zt]=de[ne]=de[te]=de[ee]=de[re]=de[ue]=!1;var me="object"==typeof n&&n&&!n.nodeType&&n,ge=me&&"object"==typeof module&&module&&!module.nodeType&&module,be=ge&&ge.exports===me,je=be&&st.process,Se=function(){try{return je&&je.binding("util")}catch(n){}}(),ke=Se&&Se.isTypedArray,Le=ke?w(ke):O,Oe=Object.prototype,we=Oe.hasOwnProperty,xe=Object.prototype,Ee=A(Object.keys,Object),Ae=Object.prototype,Te=Ae.hasOwnProperty,Be=V(P,1/0),Fe=function(n,t,e){var r=d(n)?q:Be;r(n,a(t),e)},Ie=D(R),_e=l(Ie),Me=C(R),Ue=V(Me,1),ze=l(Ue),Pe=function(n){var e=t(arguments,1);return function(){var r=t(arguments);return n.apply(null,e.concat(r))}},Ve=W(),qe=function(n,e,r){function u(n,t){j.push(function(){f(n,t)})}function o(){if(0===j.length&&0===v)return r(null,y);for(;j.length&&v<e;){var n=j.shift();n()}}function i(n,t){var e=b[n];e||(e=b[n]=[]),e.push(t)}function c(n){var t=b[n]||[];$(t,function(n){n()}),o()}function f(n,e){if(!d){var u=U(function(e,u){if(v--,arguments.length>2&&(u=t(arguments,1)),e){var o={};N(y,function(n,t){o[t]=n}),o[n]=u,d=!0,b=Object.create(null),r(e,o)}else y[n]=u,c(n)});v++;var o=a(e[e.length-1]);e.length>1?o(y,u):o(u)}}function l(){for(var n,t=0;S.length;)n=S.pop(),t++,$(s(n),function(n){0===--k[n]&&S.push(n)});if(t!==h)throw new Error("async.auto cannot execute tasks due to a recursive dependency")}function s(t){var e=[];return N(n,function(n,r){Pt(n)&&J(n,t,0)>=0&&e.push(r)}),e}"function"==typeof e&&(r=e,e=null),r=g(r||m);var p=B(n),h=p.length;if(!h)return r(null);e||(e=h);var y={},v=0,d=!1,b=Object.create(null),j=[],S=[],k={};N(n,function(t,e){if(!Pt(t))return u(e,[t]),void S.push(e);var r=t.slice(0,t.length-1),o=r.length;return 0===o?(u(e,t),void S.push(e)):(k[e]=o,void $(r,function(c){if(!n[c])throw new Error("async.auto task `"+e+"` has a non-existent dependency `"+c+"` in "+r.join(", "));i(c,function(){o--,0===o&&u(e,t)})}))}),l(),o()},De="[object Symbol]",Re=1/0,Ce=yt?yt.prototype:void 0,$e=Ce?Ce.toString:void 0,We="\\ud800-\\udfff",Ne="\\u0300-\\u036f\\ufe20-\\ufe23",Qe="\\u20d0-\\u20f0",Ge="\\ufe0e\\ufe0f",He="\\u200d",Je=RegExp("["+He+We+Ne+Qe+Ge+"]"),Ke="\\ud800-\\udfff",Xe="\\u0300-\\u036f\\ufe20-\\ufe23",Ye="\\u20d0-\\u20f0",Ze="\\ufe0e\\ufe0f",nr="["+Ke+"]",tr="["+Xe+Ye+"]",er="\\ud83c[\\udffb-\\udfff]",rr="(?:"+tr+"|"+er+")",ur="[^"+Ke+"]",or="(?:\\ud83c[\\udde6-\\uddff]){2}",ir="[\\ud800-\\udbff][\\udc00-\\udfff]",cr="\\u200d",fr=rr+"?",ar="["+Ze+"]?",lr="(?:"+cr+"(?:"+[ur,or,ir].join("|")+")"+ar+fr+")*",sr=ar+fr+lr,pr="(?:"+[ur+tr+"?",tr,or,ir,nr].join("|")+")",hr=RegExp(er+"(?="+er+")|"+pr+sr,"g"),yr=/^\s+|\s+$/g,vr=/^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m,dr=/,/,mr=/(=.+)?(\s*)$/,gr=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;pn.prototype.removeLink=function(n){return n.prev?n.prev.next=n.next:this.head=n.next,n.next?n.next.prev=n.prev:this.tail=n.prev,n.prev=n.next=null,this.length-=1,n},pn.prototype.empty=function(){for(;this.head;)this.shift();return this},pn.prototype.insertAfter=function(n,t){t.prev=n,t.next=n.next,n.next?n.next.prev=t:this.tail=t,n.next=t,this.length+=1},pn.prototype.insertBefore=function(n,t){t.prev=n.prev,t.next=n,n.prev?n.prev.next=t:this.head=t,n.prev=t,this.length+=1},pn.prototype.unshift=function(n){this.head?this.insertBefore(this.head,n):hn(this,n)},pn.prototype.push=function(n){this.tail?this.insertAfter(this.tail,n):hn(this,n)},pn.prototype.shift=function(){return this.head&&this.removeLink(this.head)},pn.prototype.pop=function(){return this.tail&&this.removeLink(this.tail)},pn.prototype.toArray=function(){for(var n=Array(this.length),t=this.head,e=0;e<this.length;e++)n[e]=t.data,t=t.next;return n},pn.prototype.remove=function(n){for(var t=this.head;t;){var e=t.next;n(t)&&this.removeLink(t),t=e}return this};var br,jr=V(P,1),Sr=function(){return mn.apply(null,t(arguments).reverse())},kr=Array.prototype.concat,Lr=function(n,e,r,u){u=u||m;var o=a(r);Me(n,e,function(n,e){o(n,function(n){return n?e(n):e(null,t(arguments,1))})},function(n,t){for(var e=[],r=0;r<t.length;r++)t[r]&&(e=kr.apply(e,t[r]));return u(n,e)})},Or=V(Lr,1/0),wr=V(Lr,1),xr=function(){var n=t(arguments),e=[null].concat(n);return function(){var n=arguments[arguments.length-1];return n.apply(this,e)}},Er=D(bn(gn,jn)),Ar=C(bn(gn,jn)),Tr=V(Ar,1),Br=Sn("dir"),Fr=V(An,1),Ir=D(bn(Bn,Bn)),_r=C(bn(Bn,Bn)),Mr=V(_r,1),Ur=D(Mn),zr=C(Mn),Pr=V(zr,1),Vr=function(n,t,e,r){r=r||m;var u=a(e);Me(n,t,function(n,t){u(n,function(e,r){return e?t(e):t(null,{key:r,val:n})})},function(n,t){for(var e={},u=Object.prototype.hasOwnProperty,o=0;o<t.length;o++)if(t[o]){var i=t[o].key,c=t[o].val;u.call(e,i)?e[i].push(c):e[i]=[c]}return r(n,e)})},qr=V(Vr,1/0),Dr=V(Vr,1),Rr=Sn("log"),Cr=V(zn,1/0),$r=V(zn,1);br=ft?process.nextTick:ct?setImmediate:r;var Wr=u(br),Nr=function(n,t){var e=a(n);return yn(function(n,t){e(n[0],t)},t,1)},Qr=function(n,t){var e=Nr(n,t);return e.push=function(n,t,r){if(null==r&&(r=m),"function"!=typeof r)throw new Error("task callback must be a function");if(e.started=!0,Pt(n)||(n=[n]),0===n.length)return at(function(){e.drain()});t=t||0;for(var u=e._tasks.head;u&&t>=u.priority;)u=u.next;for(var o=0,i=n.length;o<i;o++){var c={data:n[o],priority:t,callback:r};u?e._tasks.insertBefore(u,c):e._tasks.push(c)}at(e.process)},delete e.unshift,e},Gr=D(Nn),Hr=C(Nn),Jr=V(Hr,1),Kr=function(n,t){t||(t=n,n=null);var e=a(t);return it(function(t,r){function u(n){e.apply(null,t.concat(n))}n?Hn(n,u,r):Hn(u,r)})},Xr=D(bn(Boolean,gn)),Yr=C(bn(Boolean,gn)),Zr=V(Yr,1),nu=Math.ceil,tu=Math.max,eu=V(Zn,1/0),ru=V(Zn,1),uu=function(n,e){function r(t){var e=a(n[o++]);t.push(U(u)),e.apply(null,t)}function u(u){return u||o===n.length?e.apply(null,arguments):void r(t(arguments,1))}if(e=g(e||m),!Pt(n))return e(new Error("First argument to waterfall must be an array of functions"));if(!n.length)return e();var o=0;r([])},ou={applyEach:_e,applyEachSeries:ze,apply:Pe,asyncify:o,auto:qe,autoInject:sn,cargo:vn,compose:Sr,concat:Or,concatLimit:Lr,concatSeries:wr,constant:xr,detect:Er,detectLimit:Ar,detectSeries:Tr,dir:Br,doDuring:kn,doUntil:On,doWhilst:Ln,during:wn,each:En,eachLimit:An,eachOf:Fe,eachOfLimit:P,eachOfSeries:jr,eachSeries:Fr,ensureAsync:Tn,every:Ir,everyLimit:_r,everySeries:Mr,filter:Ur,filterLimit:zr,filterSeries:Pr,forever:Un,groupBy:qr,groupByLimit:Vr,groupBySeries:Dr,log:Rr,map:Ie,mapLimit:Me,mapSeries:Ue,mapValues:Cr,mapValuesLimit:zn,mapValuesSeries:$r,memoize:Vn,nextTick:Wr,parallel:Dn,parallelLimit:Rn,priorityQueue:Qr,queue:Nr,race:Cn,reduce:dn,reduceRight:$n,reflect:Wn,reflectAll:Qn,reject:Gr,rejectLimit:Hr,rejectSeries:Jr,retry:Hn,retryable:Kr,seq:mn,series:Jn,setImmediate:at,some:Xr,someLimit:Yr,someSeries:Zr,sortBy:Kn,timeout:Xn,times:eu,timesLimit:Zn,timesSeries:ru,transform:nt,tryEach:tt,unmemoize:et,until:ut,waterfall:uu,whilst:rt,all:Ir,any:Xr,forEach:En,forEachSeries:Fr,forEachLimit:An,forEachOf:Fe,forEachOfSeries:jr,forEachOfLimit:P,inject:dn,foldl:dn,foldr:$n,select:Ur,selectLimit:zr,selectSeries:Pr,wrapSync:o};n.default=ou,n.applyEach=_e,n.applyEachSeries=ze,n.apply=Pe,n.asyncify=o,n.auto=qe,n.autoInject=sn,n.cargo=vn,n.compose=Sr,n.concat=Or,n.concatLimit=Lr,n.concatSeries=wr,n.constant=xr,n.detect=Er,n.detectLimit=Ar,n.detectSeries=Tr,n.dir=Br,n.doDuring=kn,n.doUntil=On,n.doWhilst=Ln,n.during=wn,n.each=En,n.eachLimit=An,n.eachOf=Fe,n.eachOfLimit=P,n.eachOfSeries=jr,n.eachSeries=Fr,n.ensureAsync=Tn,n.every=Ir,n.everyLimit=_r,n.everySeries=Mr,n.filter=Ur,n.filterLimit=zr,n.filterSeries=Pr,n.forever=Un,n.groupBy=qr,n.groupByLimit=Vr,n.groupBySeries=Dr,n.log=Rr,n.map=Ie,n.mapLimit=Me,n.mapSeries=Ue,n.mapValues=Cr,n.mapValuesLimit=zn,n.mapValuesSeries=$r,n.memoize=Vn,n.nextTick=Wr,n.parallel=Dn,n.parallelLimit=Rn,n.priorityQueue=Qr,n.queue=Nr,n.race=Cn,n.reduce=dn,n.reduceRight=$n,n.reflect=Wn,n.reflectAll=Qn,n.reject=Gr,n.rejectLimit=Hr,n.rejectSeries=Jr,n.retry=Hn,n.retryable=Kr,n.seq=mn,n.series=Jn,n.setImmediate=at,n.some=Xr,n.someLimit=Yr,n.someSeries=Zr,n.sortBy=Kn,n.timeout=Xn,n.times=eu,n.timesLimit=Zn,n.timesSeries=ru,n.transform=nt,n.tryEach=tt,n.unmemoize=et,n.until=ut,n.waterfall=uu,n.whilst=rt,n.all=Ir,n.allLimit=_r,n.allSeries=Mr,n.any=Xr,n.anyLimit=Yr,n.anySeries=Zr,n.find=Er,n.findLimit=Ar,n.findSeries=Tr,n.forEach=En,n.forEachSeries=Fr,n.forEachLimit=An,n.forEachOf=Fe,n.forEachOfSeries=jr,n.forEachOfLimit=P,n.inject=dn,n.foldl=dn,n.foldr=$n,n.select=Ur,n.selectLimit=zr,n.selectSeries=Pr,n.wrapSync=o,Object.defineProperty(n,"__esModule",{value:!0})});
-//# sourceMappingURL=async.min.map \ No newline at end of file
+!function(){function n(){}function t(n){return n}function e(n){return!!n}function r(n){return!n}function u(n){return function(){if(null===n)throw new Error("Callback was already called.");n.apply(this,arguments),n=null}}function i(n){return function(){null!==n&&(n.apply(this,arguments),n=null)}}function o(n){return M(n)||"number"==typeof n.length&&n.length>=0&&n.length%1===0}function c(n,t){for(var e=-1,r=n.length;++e<r;)t(n[e],e,n)}function a(n,t){for(var e=-1,r=n.length,u=Array(r);++e<r;)u[e]=t(n[e],e,n);return u}function f(n){return a(Array(n),function(n,t){return t})}function l(n,t,e){return c(n,function(n,r,u){e=t(e,n,r,u)}),e}function s(n,t){c(W(n),function(e){t(n[e],e)})}function p(n,t){for(var e=0;e<n.length;e++)if(n[e]===t)return e;return-1}function h(n){var t,e,r=-1;return o(n)?(t=n.length,function(){return r++,t>r?r:null}):(e=W(n),t=e.length,function(){return r++,t>r?e[r]:null})}function m(n,t){return t=null==t?n.length-1:+t,function(){for(var e=Math.max(arguments.length-t,0),r=Array(e),u=0;e>u;u++)r[u]=arguments[u+t];switch(t){case 0:return n.call(this,r);case 1:return n.call(this,arguments[0],r)}}}function y(n){return function(t,e,r){return n(t,r)}}function v(t){return function(e,r,o){o=i(o||n),e=e||[];var c=h(e);if(0>=t)return o(null);var a=!1,f=0,l=!1;!function s(){if(a&&0>=f)return o(null);for(;t>f&&!l;){var n=c();if(null===n)return a=!0,void(0>=f&&o(null));f+=1,r(e[n],n,u(function(n){f-=1,n?(o(n),l=!0):s()}))}}()}}function d(n){return function(t,e,r){return n(P.eachOf,t,e,r)}}function g(n){return function(t,e,r,u){return n(v(e),t,r,u)}}function k(n){return function(t,e,r){return n(P.eachOfSeries,t,e,r)}}function b(t,e,r,u){u=i(u||n),e=e||[];var c=o(e)?[]:{};t(e,function(n,t,e){r(n,function(n,r){c[t]=r,e(n)})},function(n){u(n,c)})}function w(n,t,e,r){var u=[];n(t,function(n,t,r){e(n,function(e){e&&u.push({index:t,value:n}),r()})},function(){r(a(u.sort(function(n,t){return n.index-t.index}),function(n){return n.value}))})}function O(n,t,e,r){w(n,t,function(n,t){e(n,function(n){t(!n)})},r)}function S(n,t,e){return function(r,u,i,o){function c(){o&&o(e(!1,void 0))}function a(n,r,u){return o?void i(n,function(r){o&&t(r)&&(o(e(!0,n)),o=i=!1),u()}):u()}arguments.length>3?n(r,u,a,c):(o=i,i=u,n(r,a,c))}}function E(n,t){return t}function L(t,e,r){r=r||n;var u=o(e)?[]:{};t(e,function(n,t,e){n(m(function(n,r){r.length<=1&&(r=r[0]),u[t]=r,e(n)}))},function(n){r(n,u)})}function j(n,t,e,r){var u=[];n(t,function(n,t,r){e(n,function(n,t){u=u.concat(t||[]),r(n)})},function(n){r(n,u)})}function I(t,e,r){function i(t,e,r,u){if(null!=u&&"function"!=typeof u)throw new Error("task callback must be a function");return t.started=!0,M(e)||(e=[e]),0===e.length&&t.idle()?P.setImmediate(function(){t.drain()}):(c(e,function(e){var i={data:e,callback:u||n};r?t.tasks.unshift(i):t.tasks.push(i),t.tasks.length===t.concurrency&&t.saturated()}),void P.setImmediate(t.process))}function o(n,t){return function(){f-=1;var e=!1,r=arguments;c(t,function(n){c(l,function(t,r){t!==n||e||(l.splice(r,1),e=!0)}),n.callback.apply(n,r)}),n.tasks.length+f===0&&n.drain(),n.process()}}if(null==e)e=1;else if(0===e)throw new Error("Concurrency must not be zero");var f=0,l=[],s={tasks:[],concurrency:e,payload:r,saturated:n,empty:n,drain:n,started:!1,paused:!1,push:function(n,t){i(s,n,!1,t)},kill:function(){s.drain=n,s.tasks=[]},unshift:function(n,t){i(s,n,!0,t)},process:function(){for(;!s.paused&&f<s.concurrency&&s.tasks.length;){var n=s.payload?s.tasks.splice(0,s.payload):s.tasks.splice(0,s.tasks.length),e=a(n,function(n){return n.data});0===s.tasks.length&&s.empty(),f+=1,l.push(n[0]);var r=u(o(s,n));t(e,r)}},length:function(){return s.tasks.length},running:function(){return f},workersList:function(){return l},idle:function(){return s.tasks.length+f===0},pause:function(){s.paused=!0},resume:function(){if(s.paused!==!1){s.paused=!1;for(var n=Math.min(s.concurrency,s.tasks.length),t=1;n>=t;t++)P.setImmediate(s.process)}}};return s}function x(n){return m(function(t,e){t.apply(null,e.concat([m(function(t,e){"object"==typeof console&&(t?console.error&&console.error(t):console[n]&&c(e,function(t){console[n](t)}))})]))})}function A(n){return function(t,e,r){n(f(t),e,r)}}function T(n){return m(function(t,e){var r=m(function(e){var r=this,u=e.pop();return n(t,function(n,t,u){n.apply(r,e.concat([u]))},u)});return e.length?r.apply(this,e):r})}function z(n){return m(function(t){var e=t.pop();t.push(function(){var n=arguments;r?P.setImmediate(function(){e.apply(null,n)}):e.apply(null,n)});var r=!0;n.apply(this,t),r=!1})}var q,P={},C="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!=C&&(q=C.async),P.noConflict=function(){return C.async=q,P};var H=Object.prototype.toString,M=Array.isArray||function(n){return"[object Array]"===H.call(n)},U=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},W=Object.keys||function(n){var t=[];for(var e in n)n.hasOwnProperty(e)&&t.push(e);return t},B="function"==typeof setImmediate&&setImmediate,D=B?function(n){B(n)}:function(n){setTimeout(n,0)};"object"==typeof process&&"function"==typeof process.nextTick?P.nextTick=process.nextTick:P.nextTick=D,P.setImmediate=B?D:P.nextTick,P.forEach=P.each=function(n,t,e){return P.eachOf(n,y(t),e)},P.forEachSeries=P.eachSeries=function(n,t,e){return P.eachOfSeries(n,y(t),e)},P.forEachLimit=P.eachLimit=function(n,t,e,r){return v(t)(n,y(e),r)},P.forEachOf=P.eachOf=function(t,e,r){function o(n){f--,n?r(n):null===c&&0>=f&&r(null)}r=i(r||n),t=t||[];for(var c,a=h(t),f=0;null!=(c=a());)f+=1,e(t[c],c,u(o));0===f&&r(null)},P.forEachOfSeries=P.eachOfSeries=function(t,e,r){function o(){var n=!0;return null===a?r(null):(e(t[a],a,u(function(t){if(t)r(t);else{if(a=c(),null===a)return r(null);n?P.setImmediate(o):o()}})),void(n=!1))}r=i(r||n),t=t||[];var c=h(t),a=c();o()},P.forEachOfLimit=P.eachOfLimit=function(n,t,e,r){v(t)(n,e,r)},P.map=d(b),P.mapSeries=k(b),P.mapLimit=g(b),P.inject=P.foldl=P.reduce=function(n,t,e,r){P.eachOfSeries(n,function(n,r,u){e(t,n,function(n,e){t=e,u(n)})},function(n){r(n,t)})},P.foldr=P.reduceRight=function(n,e,r,u){var i=a(n,t).reverse();P.reduce(i,e,r,u)},P.transform=function(n,t,e,r){3===arguments.length&&(r=e,e=t,t=M(n)?[]:{}),P.eachOf(n,function(n,r,u){e(t,n,r,u)},function(n){r(n,t)})},P.select=P.filter=d(w),P.selectLimit=P.filterLimit=g(w),P.selectSeries=P.filterSeries=k(w),P.reject=d(O),P.rejectLimit=g(O),P.rejectSeries=k(O),P.any=P.some=S(P.eachOf,e,t),P.someLimit=S(P.eachOfLimit,e,t),P.all=P.every=S(P.eachOf,r,r),P.everyLimit=S(P.eachOfLimit,r,r),P.detect=S(P.eachOf,t,E),P.detectSeries=S(P.eachOfSeries,t,E),P.detectLimit=S(P.eachOfLimit,t,E),P.sortBy=function(n,t,e){function r(n,t){var e=n.criteria,r=t.criteria;return r>e?-1:e>r?1:0}P.map(n,function(n,e){t(n,function(t,r){t?e(t):e(null,{value:n,criteria:r})})},function(n,t){return n?e(n):void e(null,a(t.sort(r),function(n){return n.value}))})},P.auto=function(t,e,r){function u(n){g.unshift(n)}function o(n){var t=p(g,n);t>=0&&g.splice(t,1)}function a(){h--,c(g.slice(0),function(n){n()})}"function"==typeof arguments[1]&&(r=e,e=null),r=i(r||n);var f=W(t),h=f.length;if(!h)return r(null);e||(e=h);var y={},v=0,d=!1,g=[];u(function(){h||r(null,y)}),c(f,function(n){function i(){return e>v&&l(k,function(n,t){return n&&y.hasOwnProperty(t)},!0)&&!y.hasOwnProperty(n)}function c(){i()&&(v++,o(c),h[h.length-1](g,y))}if(!d){for(var f,h=M(t[n])?t[n]:[t[n]],g=m(function(t,e){if(v--,e.length<=1&&(e=e[0]),t){var u={};s(y,function(n,t){u[t]=n}),u[n]=e,d=!0,r(t,u)}else y[n]=e,P.setImmediate(a)}),k=h.slice(0,h.length-1),b=k.length;b--;){if(!(f=t[k[b]]))throw new Error("Has nonexistent dependency in "+k.join(", "));if(M(f)&&p(f,n)>=0)throw new Error("Has cyclic dependencies")}i()?(v++,h[h.length-1](g,y)):u(c)}})},P.retry=function(n,t,e){function r(n,t){if("number"==typeof t)n.times=parseInt(t,10)||i;else{if("object"!=typeof t)throw new Error("Unsupported argument type for 'times': "+typeof t);n.times=parseInt(t.times,10)||i,n.interval=parseInt(t.interval,10)||o}}function u(n,t){function e(n,e){return function(r){n(function(n,t){r(!n||e,{err:n,result:t})},t)}}function r(n){return function(t){setTimeout(function(){t(null)},n)}}for(;a.times;){var u=!(a.times-=1);c.push(e(a.task,u)),!u&&a.interval>0&&c.push(r(a.interval))}P.series(c,function(t,e){e=e[e.length-1],(n||a.callback)(e.err,e.result)})}var i=5,o=0,c=[],a={times:i,interval:o},f=arguments.length;if(1>f||f>3)throw new Error("Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)");return 2>=f&&"function"==typeof n&&(e=t,t=n),"function"!=typeof n&&r(a,n),a.callback=e,a.task=t,a.callback?u():u},P.waterfall=function(t,e){function r(n){return m(function(t,u){if(t)e.apply(null,[t].concat(u));else{var i=n.next();i?u.push(r(i)):u.push(e),z(n).apply(null,u)}})}if(e=i(e||n),!M(t)){var u=new Error("First argument to waterfall must be an array of functions");return e(u)}return t.length?void r(P.iterator(t))():e()},P.parallel=function(n,t){L(P.eachOf,n,t)},P.parallelLimit=function(n,t,e){L(v(t),n,e)},P.series=function(n,t){L(P.eachOfSeries,n,t)},P.iterator=function(n){function t(e){function r(){return n.length&&n[e].apply(null,arguments),r.next()}return r.next=function(){return e<n.length-1?t(e+1):null},r}return t(0)},P.apply=m(function(n,t){return m(function(e){return n.apply(null,t.concat(e))})}),P.concat=d(j),P.concatSeries=k(j),P.whilst=function(t,e,r){if(r=r||n,t()){var u=m(function(n,i){n?r(n):t.apply(this,i)?e(u):r.apply(null,[null].concat(i))});e(u)}else r(null)},P.doWhilst=function(n,t,e){var r=0;return P.whilst(function(){return++r<=1||t.apply(this,arguments)},n,e)},P.until=function(n,t,e){return P.whilst(function(){return!n.apply(this,arguments)},t,e)},P.doUntil=function(n,t,e){return P.doWhilst(n,function(){return!t.apply(this,arguments)},e)},P.during=function(t,e,r){r=r||n;var u=m(function(n,e){n?r(n):(e.push(i),t.apply(this,e))}),i=function(n,t){n?r(n):t?e(u):r(null)};t(i)},P.doDuring=function(n,t,e){var r=0;P.during(function(n){r++<1?n(null,!0):t.apply(this,arguments)},n,e)},P.queue=function(n,t){var e=I(function(t,e){n(t[0],e)},t,1);return e},P.priorityQueue=function(t,e){function r(n,t){return n.priority-t.priority}function u(n,t,e){for(var r=-1,u=n.length-1;u>r;){var i=r+(u-r+1>>>1);e(t,n[i])>=0?r=i:u=i-1}return r}function i(t,e,i,o){if(null!=o&&"function"!=typeof o)throw new Error("task callback must be a function");return t.started=!0,M(e)||(e=[e]),0===e.length?P.setImmediate(function(){t.drain()}):void c(e,function(e){var c={data:e,priority:i,callback:"function"==typeof o?o:n};t.tasks.splice(u(t.tasks,c,r)+1,0,c),t.tasks.length===t.concurrency&&t.saturated(),P.setImmediate(t.process)})}var o=P.queue(t,e);return o.push=function(n,t,e){i(o,n,t,e)},delete o.unshift,o},P.cargo=function(n,t){return I(n,1,t)},P.log=x("log"),P.dir=x("dir"),P.memoize=function(n,e){var r={},u={},i=Object.prototype.hasOwnProperty;e=e||t;var o=m(function(t){var o=t.pop(),c=e.apply(null,t);i.call(r,c)?P.setImmediate(function(){o.apply(null,r[c])}):i.call(u,c)?u[c].push(o):(u[c]=[o],n.apply(null,t.concat([m(function(n){r[c]=n;var t=u[c];delete u[c];for(var e=0,i=t.length;i>e;e++)t[e].apply(null,n)})])))});return o.memo=r,o.unmemoized=n,o},P.unmemoize=function(n){return function(){return(n.unmemoized||n).apply(null,arguments)}},P.times=A(P.map),P.timesSeries=A(P.mapSeries),P.timesLimit=function(n,t,e,r){return P.mapLimit(f(n),t,e,r)},P.seq=function(){var t=arguments;return m(function(e){var r=this,u=e[e.length-1];"function"==typeof u?e.pop():u=n,P.reduce(t,e,function(n,t,e){t.apply(r,n.concat([m(function(n,t){e(n,t)})]))},function(n,t){u.apply(r,[n].concat(t))})})},P.compose=function(){return P.seq.apply(null,Array.prototype.reverse.call(arguments))},P.applyEach=T(P.eachOf),P.applyEachSeries=T(P.eachOfSeries),P.forever=function(t,e){function r(n){return n?i(n):void o(r)}var i=u(e||n),o=z(t);r()},P.ensureAsync=z,P.constant=m(function(n){var t=[null].concat(n);return function(n){return n.apply(this,t)}}),P.wrapSync=P.asyncify=function(n){return m(function(t){var e,r=t.pop();try{e=n.apply(this,t)}catch(u){return r(u)}U(e)&&"function"==typeof e.then?e.then(function(n){r(null,n)})["catch"](function(n){r(n.message?n:new Error(n))}):r(null,e)})},"object"==typeof module&&module.exports?module.exports=P:"function"==typeof define&&define.amd?define([],function(){return P}):C.async=P}();
+//# sourceMappingURL=dist/async.min.map \ No newline at end of file