async-rails 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da7f524b017a6b3e0272432305b4b9a7060ed87c
4
- data.tar.gz: 4d8d958efc1913e40a9e0a65aec2e0186d5d054b
3
+ metadata.gz: 58099ab2e0bc301396feb92829f5ad8016d52e35
4
+ data.tar.gz: a85e7634e0a8e88655d09a0db5f82c40be9ee9cd
5
5
  SHA512:
6
- metadata.gz: a3d594ca1af6dd222c7b38f301f918bacbe2938235944fe5ee8a3fb5bcaa54ec82050d0672d0973c76beb567322a3eed62ca0cbf483327e742720d12e61381b0
7
- data.tar.gz: b9aab7ee7c2e4ee985cec8ba615eaa48b38060ca096f26f585a2c5242c81007f5962d61d6df9ff36183614a77865587eafc2da17af6ae69354e63317117d89a8
6
+ metadata.gz: 2f77783666b3b49c38f5dd393ab3421942092d9458d23953853ada286d9986dcb3acccd7e71776803bf02f01179a0bccf5b32e72222c19623275c4eca0cf3beb
7
+ data.tar.gz: e9a779af2c7d579c40a525375fe0629c917b3dd6029c13a4559c955fb1b1d3f7dacde4dd45e8d5a6551964cf2fc5849d8f31d1c040646bd6eee558a209e3c958
@@ -1,5 +1,5 @@
1
1
  module Async
2
2
  module Rails
3
- VERSION = "2.2.0"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
@@ -90,12 +90,142 @@ var initialParams = function (fn) {
90
90
  });
91
91
  };
92
92
 
93
+ /**
94
+ * Checks if `value` is the
95
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
96
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
97
+ *
98
+ * @static
99
+ * @memberOf _
100
+ * @since 0.1.0
101
+ * @category Lang
102
+ * @param {*} value The value to check.
103
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
104
+ * @example
105
+ *
106
+ * _.isObject({});
107
+ * // => true
108
+ *
109
+ * _.isObject([1, 2, 3]);
110
+ * // => true
111
+ *
112
+ * _.isObject(_.noop);
113
+ * // => true
114
+ *
115
+ * _.isObject(null);
116
+ * // => false
117
+ */
118
+ function isObject(value) {
119
+ var type = typeof value;
120
+ return value != null && (type == 'object' || type == 'function');
121
+ }
122
+
123
+ /**
124
+ * Take a sync function and make it async, passing its return value to a
125
+ * callback. This is useful for plugging sync functions into a waterfall,
126
+ * series, or other async functions. Any arguments passed to the generated
127
+ * function will be passed to the wrapped function (except for the final
128
+ * callback argument). Errors thrown will be passed to the callback.
129
+ *
130
+ * If the function passed to `asyncify` returns a Promise, that promises's
131
+ * resolved/rejected state will be used to call the callback, rather than simply
132
+ * the synchronous return value.
133
+ *
134
+ * This also means you can asyncify ES2017 `async` functions.
135
+ *
136
+ * @name asyncify
137
+ * @static
138
+ * @memberOf module:Utils
139
+ * @method
140
+ * @alias wrapSync
141
+ * @category Util
142
+ * @param {Function} func - The synchronous funuction, or Promise-returning
143
+ * function to convert to an {@link AsyncFunction}.
144
+ * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
145
+ * invoked with `(args..., callback)`.
146
+ * @example
147
+ *
148
+ * // passing a regular synchronous function
149
+ * async.waterfall([
150
+ * async.apply(fs.readFile, filename, "utf8"),
151
+ * async.asyncify(JSON.parse),
152
+ * function (data, next) {
153
+ * // data is the result of parsing the text.
154
+ * // If there was a parsing error, it would have been caught.
155
+ * }
156
+ * ], callback);
157
+ *
158
+ * // passing a function returning a promise
159
+ * async.waterfall([
160
+ * async.apply(fs.readFile, filename, "utf8"),
161
+ * async.asyncify(function (contents) {
162
+ * return db.model.create(contents);
163
+ * }),
164
+ * function (model, next) {
165
+ * // `model` is the instantiated model object.
166
+ * // If there was an error, this function would be skipped.
167
+ * }
168
+ * ], callback);
169
+ *
170
+ * // es2017 example, though `asyncify` is not needed if your JS environment
171
+ * // supports async functions out of the box
172
+ * var q = async.queue(async.asyncify(async function(file) {
173
+ * var intermediateStep = await processFile(file);
174
+ * return await somePromise(intermediateStep)
175
+ * }));
176
+ *
177
+ * q.push(files);
178
+ */
179
+ function asyncify(func) {
180
+ return initialParams(function (args, callback) {
181
+ var result;
182
+ try {
183
+ result = func.apply(this, args);
184
+ } catch (e) {
185
+ return callback(e);
186
+ }
187
+ // if result is Promise object
188
+ if (isObject(result) && typeof result.then === 'function') {
189
+ result.then(function (value) {
190
+ callback(null, value);
191
+ }, function (err) {
192
+ callback(err.message ? err : new Error(err));
193
+ });
194
+ } else {
195
+ callback(null, result);
196
+ }
197
+ });
198
+ }
199
+
200
+ var supportsSymbol = typeof Symbol === 'function';
201
+
202
+ function supportsAsync() {
203
+ var supported;
204
+ try {
205
+ /* eslint no-eval: 0 */
206
+ supported = isAsync(eval('(async function () {})'));
207
+ } catch (e) {
208
+ supported = false;
209
+ }
210
+ return supported;
211
+ }
212
+
213
+ function isAsync(fn) {
214
+ return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction';
215
+ }
216
+
217
+ function wrapAsync(asyncFn) {
218
+ return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
219
+ }
220
+
221
+ var wrapAsync$1 = supportsAsync() ? wrapAsync : identity;
222
+
93
223
  function applyEach$1(eachfn) {
94
224
  return rest(function (fns, args) {
95
225
  var go = initialParams(function (args, callback) {
96
226
  var that = this;
97
227
  return eachfn(fns, function (fn, cb) {
98
- fn.apply(that, args.concat(cb));
228
+ wrapAsync$1(fn).apply(that, args.concat(cb));
99
229
  }, callback);
100
230
  });
101
231
  if (args.length) {
@@ -200,41 +330,12 @@ function baseGetTag(value) {
200
330
  if (value == null) {
201
331
  return value === undefined ? undefinedTag : nullTag;
202
332
  }
203
- return (symToStringTag && symToStringTag in Object(value))
333
+ value = Object(value);
334
+ return (symToStringTag && symToStringTag in value)
204
335
  ? getRawTag(value)
205
336
  : objectToString(value);
206
337
  }
207
338
 
208
- /**
209
- * Checks if `value` is the
210
- * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
211
- * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
212
- *
213
- * @static
214
- * @memberOf _
215
- * @since 0.1.0
216
- * @category Lang
217
- * @param {*} value The value to check.
218
- * @returns {boolean} Returns `true` if `value` is an object, else `false`.
219
- * @example
220
- *
221
- * _.isObject({});
222
- * // => true
223
- *
224
- * _.isObject([1, 2, 3]);
225
- * // => true
226
- *
227
- * _.isObject(_.noop);
228
- * // => true
229
- *
230
- * _.isObject(null);
231
- * // => false
232
- */
233
- function isObject(value) {
234
- var type = typeof value;
235
- return value != null && (type == 'object' || type == 'function');
236
- }
237
-
238
339
  /** `Object#toString` result references. */
239
340
  var asyncTag = '[object AsyncFunction]';
240
341
  var funcTag = '[object Function]';
@@ -639,7 +740,7 @@ var freeProcess = moduleExports$1 && freeGlobal.process;
639
740
  /** Used to access faster Node.js helpers. */
640
741
  var nodeUtil = (function() {
641
742
  try {
642
- return freeProcess && freeProcess.binding && freeProcess.binding('util');
743
+ return freeProcess && freeProcess.binding('util');
643
744
  } catch (e) {}
644
745
  }());
645
746
 
@@ -899,17 +1000,15 @@ function _eachOfLimit(limit) {
899
1000
  * @category Collection
900
1001
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
901
1002
  * @param {number} limit - The maximum number of async operations at a time.
902
- * @param {Function} iteratee - A function to apply to each
1003
+ * @param {AsyncFunction} iteratee - An async function to apply to each
903
1004
  * item in `coll`. The `key` is the item's key, or index in the case of an
904
- * array. The iteratee is passed a `callback(err)` which must be called once it
905
- * has completed. If no error has occurred, the callback should be run without
906
- * arguments or with an explicit `null` argument. Invoked with
907
- * (item, key, callback).
1005
+ * array.
1006
+ * Invoked with (item, key, callback).
908
1007
  * @param {Function} [callback] - A callback which is called when all
909
1008
  * `iteratee` functions have finished, or an error occurs. Invoked with (err).
910
1009
  */
911
1010
  function eachOfLimit(coll, limit, iteratee, callback) {
912
- _eachOfLimit(limit)(coll, iteratee, callback);
1011
+ _eachOfLimit(limit)(coll, wrapAsync$1(iteratee), callback);
913
1012
  }
914
1013
 
915
1014
  function doLimit(fn, limit) {
@@ -956,12 +1055,10 @@ var eachOfGeneric = doLimit(eachOfLimit, Infinity);
956
1055
  * @category Collection
957
1056
  * @see [async.each]{@link module:Collections.each}
958
1057
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
959
- * @param {Function} iteratee - A function to apply to each
960
- * item in `coll`. The `key` is the item's key, or index in the case of an
961
- * array. The iteratee is passed a `callback(err)` which must be called once it
962
- * has completed. If no error has occurred, the callback should be run without
963
- * arguments or with an explicit `null` argument. Invoked with
964
- * (item, key, callback).
1058
+ * @param {AsyncFunction} iteratee - A function to apply to each
1059
+ * item in `coll`.
1060
+ * The `key` is the item's key, or index in the case of an array.
1061
+ * Invoked with (item, key, callback).
965
1062
  * @param {Function} [callback] - A callback which is called when all
966
1063
  * `iteratee` functions have finished, or an error occurs. Invoked with (err).
967
1064
  * @example
@@ -987,12 +1084,12 @@ var eachOfGeneric = doLimit(eachOfLimit, Infinity);
987
1084
  */
988
1085
  var eachOf = function (coll, iteratee, callback) {
989
1086
  var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
990
- eachOfImplementation(coll, iteratee, callback);
1087
+ eachOfImplementation(coll, wrapAsync$1(iteratee), callback);
991
1088
  };
992
1089
 
993
1090
  function doParallel(fn) {
994
1091
  return function (obj, iteratee, callback) {
995
- return fn(eachOf, obj, iteratee, callback);
1092
+ return fn(eachOf, obj, wrapAsync$1(iteratee), callback);
996
1093
  };
997
1094
  }
998
1095
 
@@ -1001,10 +1098,11 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
1001
1098
  arr = arr || [];
1002
1099
  var results = [];
1003
1100
  var counter = 0;
1101
+ var _iteratee = wrapAsync$1(iteratee);
1004
1102
 
1005
1103
  eachfn(arr, function (value, _, callback) {
1006
1104
  var index = counter++;
1007
- iteratee(value, function (err, v) {
1105
+ _iteratee(value, function (err, v) {
1008
1106
  results[index] = v;
1009
1107
  callback(err);
1010
1108
  });
@@ -1028,7 +1126,7 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
1028
1126
  *
1029
1127
  * If `map` is passed an Object, the results will be an Array. The results
1030
1128
  * will roughly be in the order of the original Objects' keys (but this can
1031
- * vary across JavaScript engines)
1129
+ * vary across JavaScript engines).
1032
1130
  *
1033
1131
  * @name map
1034
1132
  * @static
@@ -1036,10 +1134,10 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
1036
1134
  * @method
1037
1135
  * @category Collection
1038
1136
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
1039
- * @param {Function} iteratee - A function to apply to each item in `coll`.
1040
- * The iteratee is passed a `callback(err, transformed)` which must be called
1041
- * once it has completed with an error (which can be `null`) and a
1042
- * transformed item. Invoked with (item, callback).
1137
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
1138
+ * `coll`.
1139
+ * The iteratee should complete with the transformed item.
1140
+ * Invoked with (item, callback).
1043
1141
  * @param {Function} [callback] - A callback which is called when all `iteratee`
1044
1142
  * functions have finished, or an error occurs. Results is an Array of the
1045
1143
  * transformed items from the `coll`. Invoked with (err, results).
@@ -1063,7 +1161,7 @@ var map = doParallel(_asyncMap);
1063
1161
  * @memberOf module:ControlFlow
1064
1162
  * @method
1065
1163
  * @category Control Flow
1066
- * @param {Array|Iterable|Object} fns - A collection of asynchronous functions
1164
+ * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s
1067
1165
  * to all call with the same arguments
1068
1166
  * @param {...*} [args] - any number of separate arguments to pass to the
1069
1167
  * function.
@@ -1088,7 +1186,7 @@ var applyEach = applyEach$1(map);
1088
1186
 
1089
1187
  function doParallelLimit(fn) {
1090
1188
  return function (obj, limit, iteratee, callback) {
1091
- return fn(_eachOfLimit(limit), obj, iteratee, callback);
1189
+ return fn(_eachOfLimit(limit), obj, wrapAsync$1(iteratee), callback);
1092
1190
  };
1093
1191
  }
1094
1192
 
@@ -1103,10 +1201,10 @@ function doParallelLimit(fn) {
1103
1201
  * @category Collection
1104
1202
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
1105
1203
  * @param {number} limit - The maximum number of async operations at a time.
1106
- * @param {Function} iteratee - A function to apply to each item in `coll`.
1107
- * The iteratee is passed a `callback(err, transformed)` which must be called
1108
- * once it has completed with an error (which can be `null`) and a transformed
1109
- * item. Invoked with (item, callback).
1204
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
1205
+ * `coll`.
1206
+ * The iteratee should complete with the transformed item.
1207
+ * Invoked with (item, callback).
1110
1208
  * @param {Function} [callback] - A callback which is called when all `iteratee`
1111
1209
  * functions have finished, or an error occurs. Results is an array of the
1112
1210
  * transformed items from the `coll`. Invoked with (err, results).
@@ -1123,10 +1221,10 @@ var mapLimit = doParallelLimit(_asyncMap);
1123
1221
  * @see [async.map]{@link module:Collections.map}
1124
1222
  * @category Collection
1125
1223
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
1126
- * @param {Function} iteratee - A function to apply to each item in `coll`.
1127
- * The iteratee is passed a `callback(err, transformed)` which must be called
1128
- * once it has completed with an error (which can be `null`) and a
1129
- * transformed item. Invoked with (item, callback).
1224
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
1225
+ * `coll`.
1226
+ * The iteratee should complete with the transformed item.
1227
+ * Invoked with (item, callback).
1130
1228
  * @param {Function} [callback] - A callback which is called when all `iteratee`
1131
1229
  * functions have finished, or an error occurs. Results is an array of the
1132
1230
  * transformed items from the `coll`. Invoked with (err, results).
@@ -1142,7 +1240,7 @@ var mapSeries = doLimit(mapLimit, 1);
1142
1240
  * @method
1143
1241
  * @see [async.applyEach]{@link module:ControlFlow.applyEach}
1144
1242
  * @category Control Flow
1145
- * @param {Array|Iterable|Object} fns - A collection of asynchronous functions to all
1243
+ * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s to all
1146
1244
  * call with the same arguments
1147
1245
  * @param {...*} [args] - any number of separate arguments to pass to the
1148
1246
  * function.
@@ -1204,82 +1302,6 @@ var apply$2 = rest(function (fn, args) {
1204
1302
  });
1205
1303
  });
1206
1304
 
1207
- /**
1208
- * Take a sync function and make it async, passing its return value to a
1209
- * callback. This is useful for plugging sync functions into a waterfall,
1210
- * series, or other async functions. Any arguments passed to the generated
1211
- * function will be passed to the wrapped function (except for the final
1212
- * callback argument). Errors thrown will be passed to the callback.
1213
- *
1214
- * If the function passed to `asyncify` returns a Promise, that promises's
1215
- * resolved/rejected state will be used to call the callback, rather than simply
1216
- * the synchronous return value.
1217
- *
1218
- * This also means you can asyncify ES2016 `async` functions.
1219
- *
1220
- * @name asyncify
1221
- * @static
1222
- * @memberOf module:Utils
1223
- * @method
1224
- * @alias wrapSync
1225
- * @category Util
1226
- * @param {Function} func - The synchronous function to convert to an
1227
- * asynchronous function.
1228
- * @returns {Function} An asynchronous wrapper of the `func`. To be invoked with
1229
- * (callback).
1230
- * @example
1231
- *
1232
- * // passing a regular synchronous function
1233
- * async.waterfall([
1234
- * async.apply(fs.readFile, filename, "utf8"),
1235
- * async.asyncify(JSON.parse),
1236
- * function (data, next) {
1237
- * // data is the result of parsing the text.
1238
- * // If there was a parsing error, it would have been caught.
1239
- * }
1240
- * ], callback);
1241
- *
1242
- * // passing a function returning a promise
1243
- * async.waterfall([
1244
- * async.apply(fs.readFile, filename, "utf8"),
1245
- * async.asyncify(function (contents) {
1246
- * return db.model.create(contents);
1247
- * }),
1248
- * function (model, next) {
1249
- * // `model` is the instantiated model object.
1250
- * // If there was an error, this function would be skipped.
1251
- * }
1252
- * ], callback);
1253
- *
1254
- * // es6 example
1255
- * var q = async.queue(async.asyncify(async function(file) {
1256
- * var intermediateStep = await processFile(file);
1257
- * return await somePromise(intermediateStep)
1258
- * }));
1259
- *
1260
- * q.push(files);
1261
- */
1262
- function asyncify(func) {
1263
- return initialParams(function (args, callback) {
1264
- var result;
1265
- try {
1266
- result = func.apply(this, args);
1267
- } catch (e) {
1268
- return callback(e);
1269
- }
1270
- // if result is Promise object
1271
- if (isObject(result) && typeof result.then === 'function') {
1272
- result.then(function (value) {
1273
- callback(null, value);
1274
- }, function (err) {
1275
- callback(err.message ? err : new Error(err));
1276
- });
1277
- } else {
1278
- callback(null, result);
1279
- }
1280
- });
1281
- }
1282
-
1283
1305
  /**
1284
1306
  * A specialized version of `_.forEach` for arrays without support for
1285
1307
  * iteratee shorthands.
@@ -1422,17 +1444,17 @@ function baseIndexOf(array, value, fromIndex) {
1422
1444
  }
1423
1445
 
1424
1446
  /**
1425
- * Determines the best order for running the functions in `tasks`, based on
1447
+ * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
1426
1448
  * their requirements. Each function can optionally depend on other functions
1427
1449
  * being completed first, and each function is run as soon as its requirements
1428
1450
  * are satisfied.
1429
1451
  *
1430
- * If any of the functions pass an error to their callback, the `auto` sequence
1452
+ * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
1431
1453
  * will stop. Further tasks will not execute (so any other functions depending
1432
1454
  * on it will not run), and the main `callback` is immediately called with the
1433
1455
  * error.
1434
1456
  *
1435
- * Functions also receive an object containing the results of functions which
1457
+ * {@link AsyncFunction}s also receive an object containing the results of functions which
1436
1458
  * have completed so far as the first argument, if they have dependencies. If a
1437
1459
  * task function has no dependencies, it will only be passed a callback.
1438
1460
  *
@@ -1442,7 +1464,7 @@ function baseIndexOf(array, value, fromIndex) {
1442
1464
  * @method
1443
1465
  * @category Control Flow
1444
1466
  * @param {Object} tasks - An object. Each of its properties is either a
1445
- * function or an array of requirements, with the function itself the last item
1467
+ * function or an array of requirements, with the {@link AsyncFunction} itself the last item
1446
1468
  * in the array. The object's key of a property serves as the name of the task
1447
1469
  * defined by that property, i.e. can be used when specifying requirements for
1448
1470
  * other tasks. The function receives one or two arguments:
@@ -1620,7 +1642,7 @@ var auto = function (tasks, concurrency, callback) {
1620
1642
  }));
1621
1643
 
1622
1644
  runningTasks++;
1623
- var taskFn = task[task.length - 1];
1645
+ var taskFn = wrapAsync$1(task[task.length - 1]);
1624
1646
  if (task.length > 1) {
1625
1647
  taskFn(results, taskCallback);
1626
1648
  } else {
@@ -1827,17 +1849,15 @@ function asciiToArray(string) {
1827
1849
 
1828
1850
  /** Used to compose unicode character classes. */
1829
1851
  var rsAstralRange = '\\ud800-\\udfff';
1830
- var rsComboMarksRange = '\\u0300-\\u036f';
1831
- var reComboHalfMarksRange = '\\ufe20-\\ufe2f';
1832
- var rsComboSymbolsRange = '\\u20d0-\\u20ff';
1833
- var rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange;
1852
+ var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23';
1853
+ var rsComboSymbolsRange = '\\u20d0-\\u20f0';
1834
1854
  var rsVarRange = '\\ufe0e\\ufe0f';
1835
1855
 
1836
1856
  /** Used to compose unicode capture groups. */
1837
1857
  var rsZWJ = '\\u200d';
1838
1858
 
1839
1859
  /** 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/). */
1840
- var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
1860
+ var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
1841
1861
 
1842
1862
  /**
1843
1863
  * Checks if `string` contains Unicode symbols.
@@ -1852,15 +1872,13 @@ function hasUnicode(string) {
1852
1872
 
1853
1873
  /** Used to compose unicode character classes. */
1854
1874
  var rsAstralRange$1 = '\\ud800-\\udfff';
1855
- var rsComboMarksRange$1 = '\\u0300-\\u036f';
1856
- var reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f';
1857
- var rsComboSymbolsRange$1 = '\\u20d0-\\u20ff';
1858
- var rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1;
1875
+ var rsComboMarksRange$1 = '\\u0300-\\u036f\\ufe20-\\ufe23';
1876
+ var rsComboSymbolsRange$1 = '\\u20d0-\\u20f0';
1859
1877
  var rsVarRange$1 = '\\ufe0e\\ufe0f';
1860
1878
 
1861
1879
  /** Used to compose unicode capture groups. */
1862
1880
  var rsAstral = '[' + rsAstralRange$1 + ']';
1863
- var rsCombo = '[' + rsComboRange$1 + ']';
1881
+ var rsCombo = '[' + rsComboMarksRange$1 + rsComboSymbolsRange$1 + ']';
1864
1882
  var rsFitz = '\\ud83c[\\udffb-\\udfff]';
1865
1883
  var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')';
1866
1884
  var rsNonAstral = '[^' + rsAstralRange$1 + ']';
@@ -1968,7 +1986,7 @@ function trim(string, chars, guard) {
1968
1986
  return castSlice(strSymbols, start, end).join('');
1969
1987
  }
1970
1988
 
1971
- var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
1989
+ var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
1972
1990
  var FN_ARG_SPLIT = /,/;
1973
1991
  var FN_ARG = /(=.+)?(\s*)$/;
1974
1992
  var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
@@ -2002,7 +2020,7 @@ function parseParams(func) {
2002
2020
  * @method
2003
2021
  * @see [async.auto]{@link module:ControlFlow.auto}
2004
2022
  * @category Control Flow
2005
- * @param {Object} tasks - An object, each of whose properties is a function of
2023
+ * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
2006
2024
  * the form 'func([dependencies...], callback). The object's key of a property
2007
2025
  * serves as the name of the task defined by that property, i.e. can be used
2008
2026
  * when specifying requirements for other tasks.
@@ -2070,22 +2088,25 @@ function autoInject(tasks, callback) {
2070
2088
 
2071
2089
  baseForOwn(tasks, function (taskFn, key) {
2072
2090
  var params;
2091
+ var fnIsAsync = isAsync(taskFn);
2092
+ var hasNoDeps = !fnIsAsync && taskFn.length === 1 || fnIsAsync && taskFn.length === 0;
2073
2093
 
2074
2094
  if (isArray(taskFn)) {
2075
2095
  params = taskFn.slice(0, -1);
2076
2096
  taskFn = taskFn[taskFn.length - 1];
2077
2097
 
2078
2098
  newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
2079
- } else if (taskFn.length === 1) {
2099
+ } else if (hasNoDeps) {
2080
2100
  // no dependencies, use the function as-is
2081
2101
  newTasks[key] = taskFn;
2082
2102
  } else {
2083
2103
  params = parseParams(taskFn);
2084
- if (taskFn.length === 0 && params.length === 0) {
2104
+ if (taskFn.length === 0 && !fnIsAsync && params.length === 0) {
2085
2105
  throw new Error("autoInject task functions require explicit parameters.");
2086
2106
  }
2087
2107
 
2088
- params.pop();
2108
+ // remove callback param
2109
+ if (!fnIsAsync) params.pop();
2089
2110
 
2090
2111
  newTasks[key] = params.concat(newTask);
2091
2112
  }
@@ -2095,7 +2116,7 @@ function autoInject(tasks, callback) {
2095
2116
  return results[name];
2096
2117
  });
2097
2118
  newArgs.push(taskCb);
2098
- taskFn.apply(null, newArgs);
2119
+ wrapAsync$1(taskFn).apply(null, newArgs);
2099
2120
  }
2100
2121
  });
2101
2122
 
@@ -2193,6 +2214,10 @@ function queue(worker, concurrency, payload) {
2193
2214
  throw new Error('Concurrency must not be zero');
2194
2215
  }
2195
2216
 
2217
+ var _worker = wrapAsync$1(worker);
2218
+ var numRunning = 0;
2219
+ var workersList = [];
2220
+
2196
2221
  function _insert(data, insertAtFront, callback) {
2197
2222
  if (callback != null && typeof callback !== 'function') {
2198
2223
  throw new Error('task callback must be a function');
@@ -2225,7 +2250,7 @@ function queue(worker, concurrency, payload) {
2225
2250
 
2226
2251
  function _next(tasks) {
2227
2252
  return rest(function (args) {
2228
- workers -= 1;
2253
+ numRunning -= 1;
2229
2254
 
2230
2255
  for (var i = 0, l = tasks.length; i < l; i++) {
2231
2256
  var task = tasks[i];
@@ -2241,7 +2266,7 @@ function queue(worker, concurrency, payload) {
2241
2266
  }
2242
2267
  }
2243
2268
 
2244
- if (workers <= q.concurrency - q.buffer) {
2269
+ if (numRunning <= q.concurrency - q.buffer) {
2245
2270
  q.unsaturated();
2246
2271
  }
2247
2272
 
@@ -2252,8 +2277,6 @@ function queue(worker, concurrency, payload) {
2252
2277
  });
2253
2278
  }
2254
2279
 
2255
- var workers = 0;
2256
- var workersList = [];
2257
2280
  var isProcessing = false;
2258
2281
  var q = {
2259
2282
  _tasks: new DLL(),
@@ -2284,7 +2307,7 @@ function queue(worker, concurrency, payload) {
2284
2307
  return;
2285
2308
  }
2286
2309
  isProcessing = true;
2287
- while (!q.paused && workers < q.concurrency && q._tasks.length) {
2310
+ while (!q.paused && numRunning < q.concurrency && q._tasks.length) {
2288
2311
  var tasks = [],
2289
2312
  data = [];
2290
2313
  var l = q._tasks.length;
@@ -2298,15 +2321,15 @@ function queue(worker, concurrency, payload) {
2298
2321
  if (q._tasks.length === 0) {
2299
2322
  q.empty();
2300
2323
  }
2301
- workers += 1;
2324
+ numRunning += 1;
2302
2325
  workersList.push(tasks[0]);
2303
2326
 
2304
- if (workers === q.concurrency) {
2327
+ if (numRunning === q.concurrency) {
2305
2328
  q.saturated();
2306
2329
  }
2307
2330
 
2308
2331
  var cb = onlyOnce(_next(tasks));
2309
- worker(data, cb);
2332
+ _worker(data, cb);
2310
2333
  }
2311
2334
  isProcessing = false;
2312
2335
  },
@@ -2314,13 +2337,13 @@ function queue(worker, concurrency, payload) {
2314
2337
  return q._tasks.length;
2315
2338
  },
2316
2339
  running: function () {
2317
- return workers;
2340
+ return numRunning;
2318
2341
  },
2319
2342
  workersList: function () {
2320
2343
  return workersList;
2321
2344
  },
2322
2345
  idle: function () {
2323
- return q._tasks.length + workers === 0;
2346
+ return q._tasks.length + numRunning === 0;
2324
2347
  },
2325
2348
  pause: function () {
2326
2349
  q.paused = true;
@@ -2384,9 +2407,8 @@ function queue(worker, concurrency, payload) {
2384
2407
  * @method
2385
2408
  * @see [async.queue]{@link module:ControlFlow.queue}
2386
2409
  * @category Control Flow
2387
- * @param {Function} worker - An asynchronous function for processing an array
2388
- * of queued tasks, which must call its `callback(err)` argument when finished,
2389
- * with an optional `err` argument. Invoked with `(tasks, callback)`.
2410
+ * @param {AsyncFunction} worker - An asynchronous function for processing an array
2411
+ * of queued tasks. Invoked with `(tasks, callback)`.
2390
2412
  * @param {number} [payload=Infinity] - An optional `integer` for determining
2391
2413
  * how many tasks should be processed per round; if omitted, the default is
2392
2414
  * unlimited.
@@ -2429,11 +2451,9 @@ function cargo(worker, payload) {
2429
2451
  * @alias forEachOfSeries
2430
2452
  * @category Collection
2431
2453
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2432
- * @param {Function} iteratee - A function to apply to each item in `coll`. The
2433
- * `key` is the item's key, or index in the case of an array. The iteratee is
2434
- * passed a `callback(err)` which must be called once it has completed. If no
2435
- * error has occurred, the callback should be run without arguments or with an
2436
- * explicit `null` argument. Invoked with (item, key, callback).
2454
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
2455
+ * `coll`.
2456
+ * Invoked with (item, key, callback).
2437
2457
  * @param {Function} [callback] - A callback which is called when all `iteratee`
2438
2458
  * functions have finished, or an error occurs. Invoked with (err).
2439
2459
  */
@@ -2459,12 +2479,12 @@ var eachOfSeries = doLimit(eachOfLimit, 1);
2459
2479
  * @category Collection
2460
2480
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2461
2481
  * @param {*} memo - The initial state of the reduction.
2462
- * @param {Function} iteratee - A function applied to each item in the
2463
- * array to produce the next step in the reduction. The `iteratee` is passed a
2464
- * `callback(err, reduction)` which accepts an optional error as its first
2465
- * argument, and the state of the reduction as the second. If an error is
2466
- * passed to the callback, the reduction is stopped and the main `callback` is
2467
- * immediately called with the error. Invoked with (memo, item, callback).
2482
+ * @param {AsyncFunction} iteratee - A function applied to each item in the
2483
+ * array to produce the next step in the reduction.
2484
+ * The `iteratee` should complete with the next state of the reduction.
2485
+ * If the iteratee complete with an error, the reduction is stopped and the
2486
+ * main `callback` is immediately called with the error.
2487
+ * Invoked with (memo, item, callback).
2468
2488
  * @param {Function} [callback] - A callback which is called after all the
2469
2489
  * `iteratee` functions have finished. Result is the reduced value. Invoked with
2470
2490
  * (err, result).
@@ -2481,8 +2501,9 @@ var eachOfSeries = doLimit(eachOfLimit, 1);
2481
2501
  */
2482
2502
  function reduce(coll, memo, iteratee, callback) {
2483
2503
  callback = once(callback || noop);
2504
+ var _iteratee = wrapAsync$1(iteratee);
2484
2505
  eachOfSeries(coll, function (x, i, callback) {
2485
- iteratee(memo, x, function (err, v) {
2506
+ _iteratee(memo, x, function (err, v) {
2486
2507
  memo = v;
2487
2508
  callback(err);
2488
2509
  });
@@ -2504,7 +2525,7 @@ function reduce(coll, memo, iteratee, callback) {
2504
2525
  * @method
2505
2526
  * @see [async.compose]{@link module:ControlFlow.compose}
2506
2527
  * @category Control Flow
2507
- * @param {...Function} functions - the asynchronous functions to compose
2528
+ * @param {...AsyncFunction} functions - the asynchronous functions to compose
2508
2529
  * @returns {Function} a function that composes the `functions` in order
2509
2530
  * @example
2510
2531
  *
@@ -2530,6 +2551,7 @@ function reduce(coll, memo, iteratee, callback) {
2530
2551
  * });
2531
2552
  */
2532
2553
  var seq$1 = rest(function seq(functions) {
2554
+ var _functions = arrayMap(functions, wrapAsync$1);
2533
2555
  return rest(function (args) {
2534
2556
  var that = this;
2535
2557
 
@@ -2540,7 +2562,7 @@ var seq$1 = rest(function seq(functions) {
2540
2562
  cb = noop;
2541
2563
  }
2542
2564
 
2543
- reduce(functions, args, function (newargs, fn, cb) {
2565
+ reduce(_functions, args, function (newargs, fn, cb) {
2544
2566
  fn.apply(that, newargs.concat(rest(function (err, nextargs) {
2545
2567
  cb(err, nextargs);
2546
2568
  })));
@@ -2563,7 +2585,7 @@ var seq$1 = rest(function seq(functions) {
2563
2585
  * @memberOf module:ControlFlow
2564
2586
  * @method
2565
2587
  * @category Control Flow
2566
- * @param {...Function} functions - the asynchronous functions to compose
2588
+ * @param {...AsyncFunction} functions - the asynchronous functions to compose
2567
2589
  * @returns {Function} an asynchronous function that is the composed
2568
2590
  * asynchronous `functions`
2569
2591
  * @example
@@ -2614,10 +2636,8 @@ function concat$1(eachfn, arr, fn, callback) {
2614
2636
  * @method
2615
2637
  * @category Collection
2616
2638
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2617
- * @param {Function} iteratee - A function to apply to each item in `coll`.
2618
- * The iteratee is passed a `callback(err, results)` which must be called once
2619
- * it has completed with an error (which can be `null`) and an array of results.
2620
- * Invoked with (item, callback).
2639
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
2640
+ * which should use an array as its result. Invoked with (item, callback).
2621
2641
  * @param {Function} [callback(err)] - A callback which is called after all the
2622
2642
  * `iteratee` functions have finished, or an error occurs. Results is an array
2623
2643
  * containing the concatenated results of the `iteratee` function. Invoked with
@@ -2632,7 +2652,7 @@ var concat = doParallel(concat$1);
2632
2652
 
2633
2653
  function doSeries(fn) {
2634
2654
  return function (obj, iteratee, callback) {
2635
- return fn(eachOfSeries, obj, iteratee, callback);
2655
+ return fn(eachOfSeries, obj, wrapAsync$1(iteratee), callback);
2636
2656
  };
2637
2657
  }
2638
2658
 
@@ -2646,9 +2666,8 @@ function doSeries(fn) {
2646
2666
  * @see [async.concat]{@link module:Collections.concat}
2647
2667
  * @category Collection
2648
2668
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2649
- * @param {Function} iteratee - A function to apply to each item in `coll`.
2650
- * The iteratee is passed a `callback(err, results)` which must be called once
2651
- * it has completed with an error (which can be `null`) and an array of results.
2669
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
2670
+ * The iteratee should complete with an array an array of results.
2652
2671
  * Invoked with (item, callback).
2653
2672
  * @param {Function} [callback(err)] - A callback which is called after all the
2654
2673
  * `iteratee` functions have finished, or an error occurs. Results is an array
@@ -2669,7 +2688,7 @@ var concatSeries = doSeries(concat$1);
2669
2688
  * @category Util
2670
2689
  * @param {...*} arguments... - Any number of arguments to automatically invoke
2671
2690
  * callback with.
2672
- * @returns {Function} Returns a function that when invoked, automatically
2691
+ * @returns {AsyncFunction} Returns a function that when invoked, automatically
2673
2692
  * invokes the callback with the previous given arguments.
2674
2693
  * @example
2675
2694
  *
@@ -2754,9 +2773,9 @@ function _findGetResult(v, x) {
2754
2773
  * @alias find
2755
2774
  * @category Collections
2756
2775
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2757
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
2758
- * The iteratee is passed a `callback(err, truthValue)` which must be called
2759
- * with a boolean argument once it has completed. Invoked with (item, callback).
2776
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2777
+ * The iteratee must complete with a boolean value as its result.
2778
+ * Invoked with (item, callback).
2760
2779
  * @param {Function} [callback] - A callback which is called as soon as any
2761
2780
  * iteratee returns `true`, or after all the `iteratee` functions have finished.
2762
2781
  * Result will be the first item in the array that passes the truth test
@@ -2787,9 +2806,9 @@ var detect = doParallel(_createTester(identity, _findGetResult));
2787
2806
  * @category Collections
2788
2807
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2789
2808
  * @param {number} limit - The maximum number of async operations at a time.
2790
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
2791
- * The iteratee is passed a `callback(err, truthValue)` which must be called
2792
- * with a boolean argument once it has completed. Invoked with (item, callback).
2809
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2810
+ * The iteratee must complete with a boolean value as its result.
2811
+ * Invoked with (item, callback).
2793
2812
  * @param {Function} [callback] - A callback which is called as soon as any
2794
2813
  * iteratee returns `true`, or after all the `iteratee` functions have finished.
2795
2814
  * Result will be the first item in the array that passes the truth test
@@ -2809,9 +2828,9 @@ var detectLimit = doParallelLimit(_createTester(identity, _findGetResult));
2809
2828
  * @alias findSeries
2810
2829
  * @category Collections
2811
2830
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
2812
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
2813
- * The iteratee is passed a `callback(err, truthValue)` which must be called
2814
- * with a boolean argument once it has completed. Invoked with (item, callback).
2831
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2832
+ * The iteratee must complete with a boolean value as its result.
2833
+ * Invoked with (item, callback).
2815
2834
  * @param {Function} [callback] - A callback which is called as soon as any
2816
2835
  * iteratee returns `true`, or after all the `iteratee` functions have finished.
2817
2836
  * Result will be the first item in the array that passes the truth test
@@ -2822,7 +2841,7 @@ var detectSeries = doLimit(detectLimit, 1);
2822
2841
 
2823
2842
  function consoleFunc(name) {
2824
2843
  return rest(function (fn, args) {
2825
- fn.apply(null, args.concat(rest(function (err, args) {
2844
+ wrapAsync$1(fn).apply(null, args.concat(rest(function (err, args) {
2826
2845
  if (typeof console === 'object') {
2827
2846
  if (err) {
2828
2847
  if (console.error) {
@@ -2839,10 +2858,11 @@ function consoleFunc(name) {
2839
2858
  }
2840
2859
 
2841
2860
  /**
2842
- * Logs the result of an `async` function to the `console` using `console.dir`
2843
- * to display the properties of the resulting object. Only works in Node.js or
2844
- * in browsers that support `console.dir` and `console.error` (such as FF and
2845
- * Chrome). If multiple arguments are returned from the async function,
2861
+ * Logs the result of an [`async` function]{@link AsyncFunction} to the
2862
+ * `console` using `console.dir` to display the properties of the resulting object.
2863
+ * Only works in Node.js or in browsers that support `console.dir` and
2864
+ * `console.error` (such as FF and Chrome).
2865
+ * If multiple arguments are returned from the async function,
2846
2866
  * `console.dir` is called on each argument in order.
2847
2867
  *
2848
2868
  * @name dir
@@ -2850,8 +2870,8 @@ function consoleFunc(name) {
2850
2870
  * @memberOf module:Utils
2851
2871
  * @method
2852
2872
  * @category Util
2853
- * @param {Function} function - The function you want to eventually apply all
2854
- * arguments to.
2873
+ * @param {AsyncFunction} function - The function you want to eventually apply
2874
+ * all arguments to.
2855
2875
  * @param {...*} arguments... - Any number of arguments to apply to the function.
2856
2876
  * @example
2857
2877
  *
@@ -2879,29 +2899,30 @@ var dir = consoleFunc('dir');
2879
2899
  * @method
2880
2900
  * @see [async.during]{@link module:ControlFlow.during}
2881
2901
  * @category Control Flow
2882
- * @param {Function} fn - A function which is called each time `test` passes.
2883
- * The function is passed a `callback(err)`, which must be called once it has
2884
- * completed with an optional `err` argument. Invoked with (callback).
2885
- * @param {Function} test - asynchronous truth test to perform before each
2902
+ * @param {AsyncFunction} fn - An async function which is called each time
2903
+ * `test` passes. Invoked with (callback).
2904
+ * @param {AsyncFunction} test - asynchronous truth test to perform before each
2886
2905
  * execution of `fn`. Invoked with (...args, callback), where `...args` are the
2887
2906
  * non-error args from the previous callback of `fn`.
2888
2907
  * @param {Function} [callback] - A callback which is called after the test
2889
2908
  * function has failed and repeated execution of `fn` has stopped. `callback`
2890
- * will be passed an error if one occured, otherwise `null`.
2909
+ * will be passed an error if one occurred, otherwise `null`.
2891
2910
  */
2892
2911
  function doDuring(fn, test, callback) {
2893
2912
  callback = onlyOnce(callback || noop);
2913
+ var _fn = wrapAsync$1(fn);
2914
+ var _test = wrapAsync$1(test);
2894
2915
 
2895
2916
  var next = rest(function (err, args) {
2896
2917
  if (err) return callback(err);
2897
2918
  args.push(check);
2898
- test.apply(this, args);
2919
+ _test.apply(this, args);
2899
2920
  });
2900
2921
 
2901
2922
  function check(err, truth) {
2902
2923
  if (err) return callback(err);
2903
2924
  if (!truth) return callback(null);
2904
- fn(next);
2925
+ _fn(next);
2905
2926
  }
2906
2927
 
2907
2928
  check(null, true);
@@ -2919,11 +2940,10 @@ function doDuring(fn, test, callback) {
2919
2940
  * @method
2920
2941
  * @see [async.whilst]{@link module:ControlFlow.whilst}
2921
2942
  * @category Control Flow
2922
- * @param {Function} iteratee - A function which is called each time `test`
2923
- * passes. The function is passed a `callback(err)`, which must be called once
2924
- * it has completed with an optional `err` argument. Invoked with (callback).
2943
+ * @param {AsyncFunction} iteratee - A function which is called each time `test`
2944
+ * passes. Invoked with (callback).
2925
2945
  * @param {Function} test - synchronous truth test to perform after each
2926
- * execution of `iteratee`. Invoked with the non-error callback results of
2946
+ * execution of `iteratee`. Invoked with any non-error callback results of
2927
2947
  * `iteratee`.
2928
2948
  * @param {Function} [callback] - A callback which is called after the test
2929
2949
  * function has failed and repeated execution of `iteratee` has stopped.
@@ -2932,12 +2952,13 @@ function doDuring(fn, test, callback) {
2932
2952
  */
2933
2953
  function doWhilst(iteratee, test, callback) {
2934
2954
  callback = onlyOnce(callback || noop);
2955
+ var _iteratee = wrapAsync$1(iteratee);
2935
2956
  var next = rest(function (err, args) {
2936
2957
  if (err) return callback(err);
2937
- if (test.apply(this, args)) return iteratee(next);
2958
+ if (test.apply(this, args)) return _iteratee(next);
2938
2959
  callback.apply(null, [null].concat(args));
2939
2960
  });
2940
- iteratee(next);
2961
+ _iteratee(next);
2941
2962
  }
2942
2963
 
2943
2964
  /**
@@ -2950,18 +2971,18 @@ function doWhilst(iteratee, test, callback) {
2950
2971
  * @method
2951
2972
  * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
2952
2973
  * @category Control Flow
2953
- * @param {Function} fn - A function which is called each time `test` fails.
2954
- * The function is passed a `callback(err)`, which must be called once it has
2955
- * completed with an optional `err` argument. Invoked with (callback).
2974
+ * @param {AsyncFunction} iteratee - An async function which is called each time
2975
+ * `test` fails. Invoked with (callback).
2956
2976
  * @param {Function} test - synchronous truth test to perform after each
2957
- * execution of `fn`. Invoked with the non-error callback results of `fn`.
2977
+ * execution of `iteratee`. Invoked with any non-error callback results of
2978
+ * `iteratee`.
2958
2979
  * @param {Function} [callback] - A callback which is called after the test
2959
- * function has passed and repeated execution of `fn` has stopped. `callback`
2960
- * will be passed an error and any arguments passed to the final `fn`'s
2980
+ * function has passed and repeated execution of `iteratee` has stopped. `callback`
2981
+ * will be passed an error and any arguments passed to the final `iteratee`'s
2961
2982
  * callback. Invoked with (err, [results]);
2962
2983
  */
2963
- function doUntil(fn, test, callback) {
2964
- doWhilst(fn, function () {
2984
+ function doUntil(iteratee, test, callback) {
2985
+ doWhilst(iteratee, function () {
2965
2986
  return !test.apply(this, arguments);
2966
2987
  }, callback);
2967
2988
  }
@@ -2978,14 +2999,13 @@ function doUntil(fn, test, callback) {
2978
2999
  * @method
2979
3000
  * @see [async.whilst]{@link module:ControlFlow.whilst}
2980
3001
  * @category Control Flow
2981
- * @param {Function} test - asynchronous truth test to perform before each
3002
+ * @param {AsyncFunction} test - asynchronous truth test to perform before each
2982
3003
  * execution of `fn`. Invoked with (callback).
2983
- * @param {Function} fn - A function which is called each time `test` passes.
2984
- * The function is passed a `callback(err)`, which must be called once it has
2985
- * completed with an optional `err` argument. Invoked with (callback).
3004
+ * @param {AsyncFunction} fn - An async function which is called each time
3005
+ * `test` passes. Invoked with (callback).
2986
3006
  * @param {Function} [callback] - A callback which is called after the test
2987
3007
  * function has failed and repeated execution of `fn` has stopped. `callback`
2988
- * will be passed an error, if one occured, otherwise `null`.
3008
+ * will be passed an error, if one occurred, otherwise `null`.
2989
3009
  * @example
2990
3010
  *
2991
3011
  * var count = 0;
@@ -3005,19 +3025,21 @@ function doUntil(fn, test, callback) {
3005
3025
  */
3006
3026
  function during(test, fn, callback) {
3007
3027
  callback = onlyOnce(callback || noop);
3028
+ var _fn = wrapAsync$1(fn);
3029
+ var _test = wrapAsync$1(test);
3008
3030
 
3009
3031
  function next(err) {
3010
3032
  if (err) return callback(err);
3011
- test(check);
3033
+ _test(check);
3012
3034
  }
3013
3035
 
3014
3036
  function check(err, truth) {
3015
3037
  if (err) return callback(err);
3016
3038
  if (!truth) return callback(null);
3017
- fn(next);
3039
+ _fn(next);
3018
3040
  }
3019
3041
 
3020
- test(check);
3042
+ _test(check);
3021
3043
  }
3022
3044
 
3023
3045
  function _withoutIndex(iteratee) {
@@ -3043,12 +3065,10 @@ function _withoutIndex(iteratee) {
3043
3065
  * @alias forEach
3044
3066
  * @category Collection
3045
3067
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
3046
- * @param {Function} iteratee - A function to apply to each item
3047
- * in `coll`. The iteratee is passed a `callback(err)` which must be called once
3048
- * it has completed. If no error has occurred, the `callback` should be run
3049
- * without arguments or with an explicit `null` argument. The array index is not
3050
- * passed to the iteratee. Invoked with (item, callback). If you need the index,
3051
- * use `eachOf`.
3068
+ * @param {AsyncFunction} iteratee - An async function to apply to
3069
+ * each item in `coll`. Invoked with (item, callback).
3070
+ * The array index is not passed to the iteratee.
3071
+ * If you need the index, use `eachOf`.
3052
3072
  * @param {Function} [callback] - A callback which is called when all
3053
3073
  * `iteratee` functions have finished, or an error occurs. Invoked with (err).
3054
3074
  * @example
@@ -3086,7 +3106,7 @@ function _withoutIndex(iteratee) {
3086
3106
  * });
3087
3107
  */
3088
3108
  function eachLimit(coll, iteratee, callback) {
3089
- eachOf(coll, _withoutIndex(iteratee), callback);
3109
+ eachOf(coll, _withoutIndex(wrapAsync$1(iteratee)), callback);
3090
3110
  }
3091
3111
 
3092
3112
  /**
@@ -3101,17 +3121,16 @@ function eachLimit(coll, iteratee, callback) {
3101
3121
  * @category Collection
3102
3122
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
3103
3123
  * @param {number} limit - The maximum number of async operations at a time.
3104
- * @param {Function} iteratee - A function to apply to each item in `coll`. The
3105
- * iteratee is passed a `callback(err)` which must be called once it has
3106
- * completed. If no error has occurred, the `callback` should be run without
3107
- * arguments or with an explicit `null` argument. The array index is not passed
3108
- * to the iteratee. Invoked with (item, callback). If you need the index, use
3109
- * `eachOfLimit`.
3124
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
3125
+ * `coll`.
3126
+ * The array index is not passed to the iteratee.
3127
+ * If you need the index, use `eachOfLimit`.
3128
+ * Invoked with (item, callback).
3110
3129
  * @param {Function} [callback] - A callback which is called when all
3111
3130
  * `iteratee` functions have finished, or an error occurs. Invoked with (err).
3112
3131
  */
3113
3132
  function eachLimit$1(coll, limit, iteratee, callback) {
3114
- _eachOfLimit(limit)(coll, _withoutIndex(iteratee), callback);
3133
+ _eachOfLimit(limit)(coll, _withoutIndex(wrapAsync$1(iteratee)), callback);
3115
3134
  }
3116
3135
 
3117
3136
  /**
@@ -3125,12 +3144,11 @@ function eachLimit$1(coll, limit, iteratee, callback) {
3125
3144
  * @alias forEachSeries
3126
3145
  * @category Collection
3127
3146
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
3128
- * @param {Function} iteratee - A function to apply to each
3129
- * item in `coll`. The iteratee is passed a `callback(err)` which must be called
3130
- * once it has completed. If no error has occurred, the `callback` should be run
3131
- * without arguments or with an explicit `null` argument. The array index is
3132
- * not passed to the iteratee. Invoked with (item, callback). If you need the
3133
- * index, use `eachOfSeries`.
3147
+ * @param {AsyncFunction} iteratee - An async function to apply to each
3148
+ * item in `coll`.
3149
+ * The array index is not passed to the iteratee.
3150
+ * If you need the index, use `eachOfSeries`.
3151
+ * Invoked with (item, callback).
3134
3152
  * @param {Function} [callback] - A callback which is called when all
3135
3153
  * `iteratee` functions have finished, or an error occurs. Invoked with (err).
3136
3154
  */
@@ -3142,16 +3160,17 @@ var eachSeries = doLimit(eachLimit$1, 1);
3142
3160
  * no extra deferral is added. This is useful for preventing stack overflows
3143
3161
  * (`RangeError: Maximum call stack size exceeded`) and generally keeping
3144
3162
  * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
3145
- * contained.
3163
+ * contained. ES2017 `async` functions are returned as-is -- they are immune
3164
+ * to Zalgo's corrupting influences, as they always resolve on a later tick.
3146
3165
  *
3147
3166
  * @name ensureAsync
3148
3167
  * @static
3149
3168
  * @memberOf module:Utils
3150
3169
  * @method
3151
3170
  * @category Util
3152
- * @param {Function} fn - an async function, one that expects a node-style
3171
+ * @param {AsyncFunction} fn - an async function, one that expects a node-style
3153
3172
  * callback as its last argument.
3154
- * @returns {Function} Returns a wrapped function with the exact same call
3173
+ * @returns {AsyncFunction} Returns a wrapped function with the exact same call
3155
3174
  * signature as the function passed in.
3156
3175
  * @example
3157
3176
  *
@@ -3171,6 +3190,7 @@ var eachSeries = doLimit(eachLimit$1, 1);
3171
3190
  * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
3172
3191
  */
3173
3192
  function ensureAsync(fn) {
3193
+ if (isAsync(fn)) return fn;
3174
3194
  return initialParams(function (args, callback) {
3175
3195
  var sync = true;
3176
3196
  args.push(function () {
@@ -3203,10 +3223,10 @@ function notId(v) {
3203
3223
  * @alias all
3204
3224
  * @category Collection
3205
3225
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
3206
- * @param {Function} iteratee - A truth test to apply to each item in the
3207
- * collection in parallel. The iteratee is passed a `callback(err, truthValue)`
3208
- * which must be called with a boolean argument once it has completed. Invoked
3209
- * with (item, callback).
3226
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3227
+ * in the collection in parallel.
3228
+ * The iteratee must complete with a boolean result value.
3229
+ * Invoked with (item, callback).
3210
3230
  * @param {Function} [callback] - A callback which is called after all the
3211
3231
  * `iteratee` functions have finished. Result will be either `true` or `false`
3212
3232
  * depending on the values of the async tests. Invoked with (err, result).
@@ -3234,10 +3254,10 @@ var every = doParallel(_createTester(notId, notId));
3234
3254
  * @category Collection
3235
3255
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
3236
3256
  * @param {number} limit - The maximum number of async operations at a time.
3237
- * @param {Function} iteratee - A truth test to apply to each item in the
3238
- * collection in parallel. The iteratee is passed a `callback(err, truthValue)`
3239
- * which must be called with a boolean argument once it has completed. Invoked
3240
- * with (item, callback).
3257
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3258
+ * in the collection in parallel.
3259
+ * The iteratee must complete with a boolean result value.
3260
+ * Invoked with (item, callback).
3241
3261
  * @param {Function} [callback] - A callback which is called after all the
3242
3262
  * `iteratee` functions have finished. Result will be either `true` or `false`
3243
3263
  * depending on the values of the async tests. Invoked with (err, result).
@@ -3255,10 +3275,10 @@ var everyLimit = doParallelLimit(_createTester(notId, notId));
3255
3275
  * @alias allSeries
3256
3276
  * @category Collection
3257
3277
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
3258
- * @param {Function} iteratee - A truth test to apply to each item in the
3259
- * collection in parallel. The iteratee is passed a `callback(err, truthValue)`
3260
- * which must be called with a boolean argument once it has completed. Invoked
3261
- * with (item, callback).
3278
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3279
+ * in the collection in series.
3280
+ * The iteratee must complete with a boolean result value.
3281
+ * Invoked with (item, callback).
3262
3282
  * @param {Function} [callback] - A callback which is called after all the
3263
3283
  * `iteratee` functions have finished. Result will be either `true` or `false`
3264
3284
  * depending on the values of the async tests. Invoked with (err, result).
@@ -3321,7 +3341,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
3321
3341
 
3322
3342
  function _filter(eachfn, coll, iteratee, callback) {
3323
3343
  var filter = isArrayLike(coll) ? filterArray : filterGeneric;
3324
- filter(eachfn, coll, iteratee, callback || noop);
3344
+ filter(eachfn, coll, wrapAsync$1(iteratee), callback || noop);
3325
3345
  }
3326
3346
 
3327
3347
  /**
@@ -3397,16 +3417,16 @@ var filterSeries = doLimit(filterLimit, 1);
3397
3417
  * Calls the asynchronous function `fn` with a callback parameter that allows it
3398
3418
  * to call itself again, in series, indefinitely.
3399
3419
 
3400
- * If an error is passed to the
3401
- * callback then `errback` is called with the error, and execution stops,
3402
- * otherwise it will never be called.
3420
+ * If an error is passed to the callback then `errback` is called with the
3421
+ * error, and execution stops, otherwise it will never be called.
3403
3422
  *
3404
3423
  * @name forever
3405
3424
  * @static
3406
3425
  * @memberOf module:ControlFlow
3407
3426
  * @method
3408
3427
  * @category Control Flow
3409
- * @param {Function} fn - a function to call repeatedly. Invoked with (next).
3428
+ * @param {AsyncFunction} fn - an async function to call repeatedly.
3429
+ * Invoked with (next).
3410
3430
  * @param {Function} [errback] - when `fn` passes an error to it's callback,
3411
3431
  * this function will be called, and execution stops. Invoked with (err).
3412
3432
  * @example
@@ -3424,7 +3444,7 @@ var filterSeries = doLimit(filterLimit, 1);
3424
3444
  */
3425
3445
  function forever(fn, errback) {
3426
3446
  var done = onlyOnce(errback || noop);
3427
- var task = ensureAsync(fn);
3447
+ var task = wrapAsync$1(ensureAsync(fn));
3428
3448
 
3429
3449
  function next(err) {
3430
3450
  if (err) return done(err);
@@ -3433,6 +3453,114 @@ function forever(fn, errback) {
3433
3453
  next();
3434
3454
  }
3435
3455
 
3456
+ /**
3457
+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
3458
+ *
3459
+ * @name groupByLimit
3460
+ * @static
3461
+ * @memberOf module:Collections
3462
+ * @method
3463
+ * @see [async.groupBy]{@link module:Collections.groupBy}
3464
+ * @category Collection
3465
+ * @param {Array|Iterable|Object} coll - A collection to iterate over.
3466
+ * @param {number} limit - The maximum number of async operations at a time.
3467
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
3468
+ * `coll`.
3469
+ * The iteratee should complete with a `key` to group the value under.
3470
+ * Invoked with (value, callback).
3471
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
3472
+ * functions have finished, or an error occurs. Result is an `Object` whoses
3473
+ * properties are arrays of values which returned the corresponding key.
3474
+ */
3475
+ var groupByLimit = function (coll, limit, iteratee, callback) {
3476
+ callback = callback || noop;
3477
+ var _iteratee = wrapAsync$1(iteratee);
3478
+ mapLimit(coll, limit, function (val, callback) {
3479
+ _iteratee(val, function (err, key) {
3480
+ if (err) return callback(err);
3481
+ return callback(null, { key: key, val: val });
3482
+ });
3483
+ }, function (err, mapResults) {
3484
+ var result = {};
3485
+ // from MDN, handle object having an `hasOwnProperty` prop
3486
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
3487
+
3488
+ for (var i = 0; i < mapResults.length; i++) {
3489
+ if (mapResults[i]) {
3490
+ var key = mapResults[i].key;
3491
+ var val = mapResults[i].val;
3492
+
3493
+ if (hasOwnProperty.call(result, key)) {
3494
+ result[key].push(val);
3495
+ } else {
3496
+ result[key] = [val];
3497
+ }
3498
+ }
3499
+ }
3500
+
3501
+ return callback(err, result);
3502
+ });
3503
+ };
3504
+
3505
+ /**
3506
+ * Returns a new object, where each value corresponds to an array of items, from
3507
+ * `coll`, that returned the corresponding key. That is, the keys of the object
3508
+ * correspond to the values passed to the `iteratee` callback.
3509
+ *
3510
+ * Note: Since this function applies the `iteratee` to each item in parallel,
3511
+ * there is no guarantee that the `iteratee` functions will complete in order.
3512
+ * However, the values for each key in the `result` will be in the same order as
3513
+ * the original `coll`. For Objects, the values will roughly be in the order of
3514
+ * the original Objects' keys (but this can vary across JavaScript engines).
3515
+ *
3516
+ * @name groupBy
3517
+ * @static
3518
+ * @memberOf module:Collections
3519
+ * @method
3520
+ * @category Collection
3521
+ * @param {Array|Iterable|Object} coll - A collection to iterate over.
3522
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
3523
+ * `coll`.
3524
+ * The iteratee should complete with a `key` to group the value under.
3525
+ * Invoked with (value, callback).
3526
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
3527
+ * functions have finished, or an error occurs. Result is an `Object` whoses
3528
+ * properties are arrays of values which returned the corresponding key.
3529
+ * @example
3530
+ *
3531
+ * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) {
3532
+ * db.findById(userId, function(err, user) {
3533
+ * if (err) return callback(err);
3534
+ * return callback(null, user.age);
3535
+ * });
3536
+ * }, function(err, result) {
3537
+ * // result is object containing the userIds grouped by age
3538
+ * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']};
3539
+ * });
3540
+ */
3541
+ var groupBy = doLimit(groupByLimit, Infinity);
3542
+
3543
+ /**
3544
+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
3545
+ *
3546
+ * @name groupBySeries
3547
+ * @static
3548
+ * @memberOf module:Collections
3549
+ * @method
3550
+ * @see [async.groupBy]{@link module:Collections.groupBy}
3551
+ * @category Collection
3552
+ * @param {Array|Iterable|Object} coll - A collection to iterate over.
3553
+ * @param {number} limit - The maximum number of async operations at a time.
3554
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
3555
+ * `coll`.
3556
+ * The iteratee should complete with a `key` to group the value under.
3557
+ * Invoked with (value, callback).
3558
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
3559
+ * functions have finished, or an error occurs. Result is an `Object` whoses
3560
+ * properties are arrays of values which returned the corresponding key.
3561
+ */
3562
+ var groupBySeries = doLimit(groupByLimit, 1);
3563
+
3436
3564
  /**
3437
3565
  * Logs the result of an `async` function to the `console`. Only works in
3438
3566
  * Node.js or in browsers that support `console.log` and `console.error` (such
@@ -3444,8 +3572,8 @@ function forever(fn, errback) {
3444
3572
  * @memberOf module:Utils
3445
3573
  * @method
3446
3574
  * @category Util
3447
- * @param {Function} function - The function you want to eventually apply all
3448
- * arguments to.
3575
+ * @param {AsyncFunction} function - The function you want to eventually apply
3576
+ * all arguments to.
3449
3577
  * @param {...*} arguments... - Any number of arguments to apply to the function.
3450
3578
  * @example
3451
3579
  *
@@ -3474,10 +3602,10 @@ var log = consoleFunc('log');
3474
3602
  * @category Collection
3475
3603
  * @param {Object} obj - A collection to iterate over.
3476
3604
  * @param {number} limit - The maximum number of async operations at a time.
3477
- * @param {Function} iteratee - A function to apply to each value in `obj`.
3478
- * The iteratee is passed a `callback(err, transformed)` which must be called
3479
- * once it has completed with an error (which can be `null`) and a
3480
- * transformed value. Invoked with (value, key, callback).
3605
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
3606
+ * in `coll`.
3607
+ * The iteratee should complete with the transformed value as its result.
3608
+ * Invoked with (value, key, callback).
3481
3609
  * @param {Function} [callback] - A callback which is called when all `iteratee`
3482
3610
  * functions have finished, or an error occurs. `result` is a new object consisting
3483
3611
  * of each key from `obj`, with each transformed value on the right-hand side.
@@ -3486,8 +3614,9 @@ var log = consoleFunc('log');
3486
3614
  function mapValuesLimit(obj, limit, iteratee, callback) {
3487
3615
  callback = once(callback || noop);
3488
3616
  var newObj = {};
3617
+ var _iteratee = wrapAsync$1(iteratee);
3489
3618
  eachOfLimit(obj, limit, function (val, key, next) {
3490
- iteratee(val, key, function (err, result) {
3619
+ _iteratee(val, key, function (err, result) {
3491
3620
  if (err) return next(err);
3492
3621
  newObj[key] = result;
3493
3622
  next();
@@ -3516,10 +3645,10 @@ function mapValuesLimit(obj, limit, iteratee, callback) {
3516
3645
  * @method
3517
3646
  * @category Collection
3518
3647
  * @param {Object} obj - A collection to iterate over.
3519
- * @param {Function} iteratee - A function to apply to each value and key in
3520
- * `coll`. The iteratee is passed a `callback(err, transformed)` which must be
3521
- * called once it has completed with an error (which can be `null`) and a
3522
- * transformed value. Invoked with (value, key, callback).
3648
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
3649
+ * in `coll`.
3650
+ * The iteratee should complete with the transformed value as its result.
3651
+ * Invoked with (value, key, callback).
3523
3652
  * @param {Function} [callback] - A callback which is called when all `iteratee`
3524
3653
  * functions have finished, or an error occurs. `result` is a new object consisting
3525
3654
  * of each key from `obj`, with each transformed value on the right-hand side.
@@ -3554,10 +3683,10 @@ var mapValues = doLimit(mapValuesLimit, Infinity);
3554
3683
  * @see [async.mapValues]{@link module:Collections.mapValues}
3555
3684
  * @category Collection
3556
3685
  * @param {Object} obj - A collection to iterate over.
3557
- * @param {Function} iteratee - A function to apply to each value in `obj`.
3558
- * The iteratee is passed a `callback(err, transformed)` which must be called
3559
- * once it has completed with an error (which can be `null`) and a
3560
- * transformed value. Invoked with (value, key, callback).
3686
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
3687
+ * in `coll`.
3688
+ * The iteratee should complete with the transformed value as its result.
3689
+ * Invoked with (value, key, callback).
3561
3690
  * @param {Function} [callback] - A callback which is called when all `iteratee`
3562
3691
  * functions have finished, or an error occurs. `result` is a new object consisting
3563
3692
  * of each key from `obj`, with each transformed value on the right-hand side.
@@ -3570,7 +3699,7 @@ function has(obj, key) {
3570
3699
  }
3571
3700
 
3572
3701
  /**
3573
- * Caches the results of an `async` function. When creating a hash to store
3702
+ * Caches the results of an async function. When creating a hash to store
3574
3703
  * function results against, the callback is omitted from the hash and an
3575
3704
  * optional hash function can be used.
3576
3705
  *
@@ -3588,11 +3717,11 @@ function has(obj, key) {
3588
3717
  * @memberOf module:Utils
3589
3718
  * @method
3590
3719
  * @category Util
3591
- * @param {Function} fn - The function to proxy and cache results from.
3720
+ * @param {AsyncFunction} fn - The async function to proxy and cache results from.
3592
3721
  * @param {Function} hasher - An optional function for generating a custom hash
3593
3722
  * for storing results. It has all the arguments applied to it apart from the
3594
3723
  * callback, and must be synchronous.
3595
- * @returns {Function} a memoized version of `fn`
3724
+ * @returns {AsyncFunction} a memoized version of `fn`
3596
3725
  * @example
3597
3726
  *
3598
3727
  * var slow_fn = function(name, callback) {
@@ -3610,6 +3739,7 @@ function memoize(fn, hasher) {
3610
3739
  var memo = Object.create(null);
3611
3740
  var queues = Object.create(null);
3612
3741
  hasher = hasher || identity;
3742
+ var _fn = wrapAsync$1(fn);
3613
3743
  var memoized = initialParams(function memoized(args, callback) {
3614
3744
  var key = hasher.apply(null, args);
3615
3745
  if (has(memo, key)) {
@@ -3620,7 +3750,7 @@ function memoize(fn, hasher) {
3620
3750
  queues[key].push(callback);
3621
3751
  } else {
3622
3752
  queues[key] = [callback];
3623
- fn.apply(null, args.concat(rest(function (args) {
3753
+ _fn.apply(null, args.concat(rest(function (args) {
3624
3754
  memo[key] = args;
3625
3755
  var q = queues[key];
3626
3756
  delete queues[key];
@@ -3683,7 +3813,7 @@ function _parallel(eachfn, tasks, callback) {
3683
3813
  var results = isArrayLike(tasks) ? [] : {};
3684
3814
 
3685
3815
  eachfn(tasks, function (task, key, callback) {
3686
- task(rest(function (err, args) {
3816
+ wrapAsync$1(task)(rest(function (err, args) {
3687
3817
  if (args.length <= 1) {
3688
3818
  args = args[0];
3689
3819
  }
@@ -3708,6 +3838,9 @@ function _parallel(eachfn, tasks, callback) {
3708
3838
  * sections for each task will happen one after the other. JavaScript remains
3709
3839
  * single-threaded.
3710
3840
  *
3841
+ * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
3842
+ * execution of other tasks when a task fails.
3843
+ *
3711
3844
  * It is also possible to use an object instead of an array. Each property will
3712
3845
  * be run as a function and the results will be passed to the final `callback`
3713
3846
  * as an object instead of an array. This can be a more readable way of handling
@@ -3718,14 +3851,14 @@ function _parallel(eachfn, tasks, callback) {
3718
3851
  * @memberOf module:ControlFlow
3719
3852
  * @method
3720
3853
  * @category Control Flow
3721
- * @param {Array|Iterable|Object} tasks - A collection containing functions to run.
3722
- * Each function is passed a `callback(err, result)` which it must call on
3723
- * completion with an error `err` (which can be `null`) and an optional `result`
3724
- * value.
3854
+ * @param {Array|Iterable|Object} tasks - A collection of
3855
+ * [async functions]{@link AsyncFunction} to run.
3856
+ * Each async function can complete with any number of optional `result` values.
3725
3857
  * @param {Function} [callback] - An optional callback to run once all the
3726
3858
  * functions have completed successfully. This function gets a results array
3727
3859
  * (or object) containing all the result arguments passed to the task callbacks.
3728
3860
  * Invoked with (err, results).
3861
+ *
3729
3862
  * @example
3730
3863
  * async.parallel([
3731
3864
  * function(callback) {
@@ -3775,10 +3908,9 @@ function parallelLimit(tasks, callback) {
3775
3908
  * @method
3776
3909
  * @see [async.parallel]{@link module:ControlFlow.parallel}
3777
3910
  * @category Control Flow
3778
- * @param {Array|Collection} tasks - A collection containing functions to run.
3779
- * Each function is passed a `callback(err, result)` which it must call on
3780
- * completion with an error `err` (which can be `null`) and an optional `result`
3781
- * value.
3911
+ * @param {Array|Iterable|Object} tasks - A collection of
3912
+ * [async functions]{@link AsyncFunction} to run.
3913
+ * Each async function can complete with any number of optional `result` values.
3782
3914
  * @param {number} limit - The maximum number of async operations at a time.
3783
3915
  * @param {Function} [callback] - An optional callback to run once all the
3784
3916
  * functions have completed successfully. This function gets a results array
@@ -3847,11 +3979,9 @@ function parallelLimit$1(tasks, limit, callback) {
3847
3979
  * @memberOf module:ControlFlow
3848
3980
  * @method
3849
3981
  * @category Control Flow
3850
- * @param {Function} worker - An asynchronous function for processing a queued
3851
- * task, which must call its `callback(err)` argument when finished, with an
3852
- * optional `error` as an argument. If you want to handle errors from an
3853
- * individual task, pass a callback to `q.push()`. Invoked with
3854
- * (task, callback).
3982
+ * @param {AsyncFunction} worker - An async function for processing a queued task.
3983
+ * If you want to handle errors from an individual task, pass a callback to
3984
+ * `q.push()`. Invoked with (task, callback).
3855
3985
  * @param {number} [concurrency=1] - An `integer` for determining how many
3856
3986
  * `worker` functions should be run in parallel. If omitted, the concurrency
3857
3987
  * defaults to `1`. If the concurrency is `0`, an error is thrown.
@@ -3890,8 +4020,9 @@ function parallelLimit$1(tasks, limit, callback) {
3890
4020
  * });
3891
4021
  */
3892
4022
  var queue$1 = function (worker, concurrency) {
4023
+ var _worker = wrapAsync$1(worker);
3893
4024
  return queue(function (items, cb) {
3894
- worker(items[0], cb);
4025
+ _worker(items[0], cb);
3895
4026
  }, concurrency, 1);
3896
4027
  };
3897
4028
 
@@ -3905,11 +4036,10 @@ var queue$1 = function (worker, concurrency) {
3905
4036
  * @method
3906
4037
  * @see [async.queue]{@link module:ControlFlow.queue}
3907
4038
  * @category Control Flow
3908
- * @param {Function} worker - An asynchronous function for processing a queued
3909
- * task, which must call its `callback(err)` argument when finished, with an
3910
- * optional `error` as an argument. If you want to handle errors from an
3911
- * individual task, pass a callback to `q.push()`. Invoked with
3912
- * (task, callback).
4039
+ * @param {AsyncFunction} worker - An async function for processing a queued task.
4040
+ * If you want to handle errors from an individual task, pass a callback to
4041
+ * `q.push()`.
4042
+ * Invoked with (task, callback).
3913
4043
  * @param {number} concurrency - An `integer` for determining how many `worker`
3914
4044
  * functions should be run in parallel. If omitted, the concurrency defaults to
3915
4045
  * `1`. If the concurrency is `0`, an error is thrown.
@@ -3979,9 +4109,8 @@ var priorityQueue = function (worker, concurrency) {
3979
4109
  * @memberOf module:ControlFlow
3980
4110
  * @method
3981
4111
  * @category Control Flow
3982
- * @param {Array} tasks - An array containing functions to run. Each function
3983
- * is passed a `callback(err, result)` which it must call on completion with an
3984
- * error `err` (which can be `null`) and an optional `result` value.
4112
+ * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
4113
+ * to run. Each function can complete with an optional `result` value.
3985
4114
  * @param {Function} callback - A callback to run once any of the functions have
3986
4115
  * completed. This function gets an error or result from the first function that
3987
4116
  * completed. Invoked with (err, result).
@@ -4010,7 +4139,7 @@ function race(tasks, callback) {
4010
4139
  if (!isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
4011
4140
  if (!tasks.length) return callback();
4012
4141
  for (var i = 0, l = tasks.length; i < l; i++) {
4013
- tasks[i](callback);
4142
+ wrapAsync$1(tasks[i])(callback);
4014
4143
  }
4015
4144
  }
4016
4145
 
@@ -4028,12 +4157,12 @@ var slice = Array.prototype.slice;
4028
4157
  * @category Collection
4029
4158
  * @param {Array} array - A collection to iterate over.
4030
4159
  * @param {*} memo - The initial state of the reduction.
4031
- * @param {Function} iteratee - A function applied to each item in the
4032
- * array to produce the next step in the reduction. The `iteratee` is passed a
4033
- * `callback(err, reduction)` which accepts an optional error as its first
4034
- * argument, and the state of the reduction as the second. If an error is
4035
- * passed to the callback, the reduction is stopped and the main `callback` is
4036
- * immediately called with the error. Invoked with (memo, item, callback).
4160
+ * @param {AsyncFunction} iteratee - A function applied to each item in the
4161
+ * array to produce the next step in the reduction.
4162
+ * The `iteratee` should complete with the next state of the reduction.
4163
+ * If the iteratee complete with an error, the reduction is stopped and the
4164
+ * main `callback` is immediately called with the error.
4165
+ * Invoked with (memo, item, callback).
4037
4166
  * @param {Function} [callback] - A callback which is called after all the
4038
4167
  * `iteratee` functions have finished. Result is the reduced value. Invoked with
4039
4168
  * (err, result).
@@ -4044,17 +4173,17 @@ function reduceRight(array, memo, iteratee, callback) {
4044
4173
  }
4045
4174
 
4046
4175
  /**
4047
- * Wraps the function in another function that always returns data even when it
4048
- * errors.
4176
+ * Wraps the async function in another function that always completes with a
4177
+ * result object, even when it errors.
4049
4178
  *
4050
- * The object returned has either the property `error` or `value`.
4179
+ * The result object has either the property `error` or `value`.
4051
4180
  *
4052
4181
  * @name reflect
4053
4182
  * @static
4054
4183
  * @memberOf module:Utils
4055
4184
  * @method
4056
4185
  * @category Util
4057
- * @param {Function} fn - The function you want to wrap
4186
+ * @param {AsyncFunction} fn - The async function you want to wrap
4058
4187
  * @returns {Function} - A function that always passes null to it's callback as
4059
4188
  * the error. The second argument to the callback will be an `object` with
4060
4189
  * either an `error` or a `value` property.
@@ -4083,6 +4212,7 @@ function reduceRight(array, memo, iteratee, callback) {
4083
4212
  * });
4084
4213
  */
4085
4214
  function reflect(fn) {
4215
+ var _fn = wrapAsync$1(fn);
4086
4216
  return initialParams(function reflectOn(args, reflectCallback) {
4087
4217
  args.push(rest(function callback(err, cbArgs) {
4088
4218
  if (err) {
@@ -4102,7 +4232,7 @@ function reflect(fn) {
4102
4232
  }
4103
4233
  }));
4104
4234
 
4105
- return fn.apply(this, args);
4235
+ return _fn.apply(this, args);
4106
4236
  });
4107
4237
  }
4108
4238
 
@@ -4124,9 +4254,10 @@ function reject$1(eachfn, arr, iteratee, callback) {
4124
4254
  * @see [async.filter]{@link module:Collections.filter}
4125
4255
  * @category Collection
4126
4256
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4127
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
4128
- * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
4129
- * with a boolean argument once it has completed. Invoked with (item, callback).
4257
+ * @param {Function} iteratee - An async truth test to apply to each item in
4258
+ * `coll`.
4259
+ * The should complete with a boolean value as its `result`.
4260
+ * Invoked with (item, callback).
4130
4261
  * @param {Function} [callback] - A callback which is called after all the
4131
4262
  * `iteratee` functions have finished. Invoked with (err, results).
4132
4263
  * @example
@@ -4143,7 +4274,7 @@ function reject$1(eachfn, arr, iteratee, callback) {
4143
4274
  var reject = doParallel(reject$1);
4144
4275
 
4145
4276
  /**
4146
- * A helper function that wraps an array or an object of functions with reflect.
4277
+ * A helper function that wraps an array or an object of functions with `reflect`.
4147
4278
  *
4148
4279
  * @name reflectAll
4149
4280
  * @static
@@ -4151,8 +4282,9 @@ var reject = doParallel(reject$1);
4151
4282
  * @method
4152
4283
  * @see [async.reflect]{@link module:Utils.reflect}
4153
4284
  * @category Util
4154
- * @param {Array} tasks - The array of functions to wrap in `async.reflect`.
4155
- * @returns {Array} Returns an array of functions, each function wrapped in
4285
+ * @param {Array|Object|Iterable} tasks - The collection of
4286
+ * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
4287
+ * @returns {Array} Returns an array of async functions, each wrapped in
4156
4288
  * `async.reflect`
4157
4289
  * @example
4158
4290
  *
@@ -4233,9 +4365,10 @@ function reflectAll(tasks) {
4233
4365
  * @category Collection
4234
4366
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4235
4367
  * @param {number} limit - The maximum number of async operations at a time.
4236
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
4237
- * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
4238
- * with a boolean argument once it has completed. Invoked with (item, callback).
4368
+ * @param {Function} iteratee - An async truth test to apply to each item in
4369
+ * `coll`.
4370
+ * The should complete with a boolean value as its `result`.
4371
+ * Invoked with (item, callback).
4239
4372
  * @param {Function} [callback] - A callback which is called after all the
4240
4373
  * `iteratee` functions have finished. Invoked with (err, results).
4241
4374
  */
@@ -4251,9 +4384,10 @@ var rejectLimit = doParallelLimit(reject$1);
4251
4384
  * @see [async.reject]{@link module:Collections.reject}
4252
4385
  * @category Collection
4253
4386
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4254
- * @param {Function} iteratee - A truth test to apply to each item in `coll`.
4255
- * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
4256
- * with a boolean argument once it has completed. Invoked with (item, callback).
4387
+ * @param {Function} iteratee - An async truth test to apply to each item in
4388
+ * `coll`.
4389
+ * The should complete with a boolean value as its `result`.
4390
+ * Invoked with (item, callback).
4257
4391
  * @param {Function} [callback] - A callback which is called after all the
4258
4392
  * `iteratee` functions have finished. Invoked with (err, results).
4259
4393
  */
@@ -4295,6 +4429,7 @@ function constant$1(value) {
4295
4429
  * @memberOf module:ControlFlow
4296
4430
  * @method
4297
4431
  * @category Control Flow
4432
+ * @see [async.retryable]{@link module:ControlFlow.retryable}
4298
4433
  * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
4299
4434
  * object with `times` and `interval` or a number.
4300
4435
  * * `times` - The number of attempts to make before giving up. The default
@@ -4309,16 +4444,13 @@ function constant$1(value) {
4309
4444
  * Invoked with (err).
4310
4445
  * * If `opts` is a number, the number specifies the number of times to retry,
4311
4446
  * with the default interval of `0`.
4312
- * @param {Function} task - A function which receives two arguments: (1) a
4313
- * `callback(err, result)` which must be called when finished, passing `err`
4314
- * (which can be `null`) and the `result` of the function's execution, and (2)
4315
- * a `results` object, containing the results of the previously executed
4316
- * functions (if nested inside another control flow). Invoked with
4317
- * (callback, results).
4447
+ * @param {AsyncFunction} task - An async function to retry.
4448
+ * Invoked with (callback).
4318
4449
  * @param {Function} [callback] - An optional callback which is called when the
4319
4450
  * task has succeeded, or after the final failed attempt. It receives the `err`
4320
4451
  * and `result` arguments of the last attempt at completing the `task`. Invoked
4321
4452
  * with (err, results).
4453
+ *
4322
4454
  * @example
4323
4455
  *
4324
4456
  * // The `retry` function can be used as a stand-alone control flow by passing
@@ -4364,7 +4496,7 @@ function constant$1(value) {
4364
4496
  * // individual methods that are not as reliable, like this:
4365
4497
  * async.auto({
4366
4498
  * users: api.getUsers.bind(api),
4367
- * payments: async.retry(3, api.getPayments.bind(api))
4499
+ * payments: async.retryable(3, api.getPayments.bind(api))
4368
4500
  * }, function(err, results) {
4369
4501
  * // do something with the results
4370
4502
  * });
@@ -4405,9 +4537,11 @@ function retry(opts, task, callback) {
4405
4537
  throw new Error("Invalid arguments for async.retry");
4406
4538
  }
4407
4539
 
4540
+ var _task = wrapAsync$1(task);
4541
+
4408
4542
  var attempt = 1;
4409
4543
  function retryAttempt() {
4410
- task(function (err) {
4544
+ _task(function (err) {
4411
4545
  if (err && attempt++ < options.times && (typeof options.errorFilter != 'function' || options.errorFilter(err))) {
4412
4546
  setTimeout(retryAttempt, options.intervalFunc(attempt));
4413
4547
  } else {
@@ -4420,8 +4554,9 @@ function retry(opts, task, callback) {
4420
4554
  }
4421
4555
 
4422
4556
  /**
4423
- * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method wraps a task and makes it
4424
- * retryable, rather than immediately calling it with retries.
4557
+ * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method
4558
+ * wraps a task and makes it retryable, rather than immediately calling it
4559
+ * with retries.
4425
4560
  *
4426
4561
  * @name retryable
4427
4562
  * @static
@@ -4431,9 +4566,12 @@ function retry(opts, task, callback) {
4431
4566
  * @category Control Flow
4432
4567
  * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
4433
4568
  * options, exactly the same as from `retry`
4434
- * @param {Function} task - the asynchronous function to wrap
4435
- * @returns {Functions} The wrapped function, which when invoked, will retry on
4436
- * an error, based on the parameters specified in `opts`.
4569
+ * @param {AsyncFunction} task - the asynchronous function to wrap.
4570
+ * This function will be passed any arguments passed to the returned wrapper.
4571
+ * Invoked with (...args, callback).
4572
+ * @returns {AsyncFunction} The wrapped function, which when invoked, will
4573
+ * retry on an error, based on the parameters specified in `opts`.
4574
+ * This function will accept the same parameters as `task`.
4437
4575
  * @example
4438
4576
  *
4439
4577
  * async.auto({
@@ -4448,9 +4586,10 @@ var retryable = function (opts, task) {
4448
4586
  task = opts;
4449
4587
  opts = null;
4450
4588
  }
4589
+ var _task = wrapAsync$1(task);
4451
4590
  return initialParams(function (args, callback) {
4452
4591
  function taskFn(cb) {
4453
- task.apply(null, args.concat(cb));
4592
+ _task.apply(null, args.concat(cb));
4454
4593
  }
4455
4594
 
4456
4595
  if (opts) retry(opts, taskFn, callback);else retry(taskFn, callback);
@@ -4483,9 +4622,9 @@ var retryable = function (opts, task) {
4483
4622
  * @memberOf module:ControlFlow
4484
4623
  * @method
4485
4624
  * @category Control Flow
4486
- * @param {Array|Iterable|Object} tasks - A collection containing functions to run, each
4487
- * function is passed a `callback(err, result)` it must call on completion with
4488
- * an error `err` (which can be `null`) and an optional `result` value.
4625
+ * @param {Array|Iterable|Object} tasks - A collection containing
4626
+ * [async functions]{@link AsyncFunction} to run in series.
4627
+ * Each function can complete with any number of optional `result` values.
4489
4628
  * @param {Function} [callback] - An optional callback to run once all the
4490
4629
  * functions have completed. This function gets a results array (or object)
4491
4630
  * containing all the result arguments passed to the `task` callbacks. Invoked
@@ -4537,10 +4676,10 @@ function series(tasks, callback) {
4537
4676
  * @alias any
4538
4677
  * @category Collection
4539
4678
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4540
- * @param {Function} iteratee - A truth test to apply to each item in the array
4541
- * in parallel. The iteratee is passed a `callback(err, truthValue)` which must
4542
- * be called with a boolean argument once it has completed. Invoked with
4543
- * (item, callback).
4679
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4680
+ * in the collections in parallel.
4681
+ * The iteratee should complete with a boolean `result` value.
4682
+ * Invoked with (item, callback).
4544
4683
  * @param {Function} [callback] - A callback which is called as soon as any
4545
4684
  * iteratee returns `true`, or after all the iteratee functions have finished.
4546
4685
  * Result will be either `true` or `false` depending on the values of the async
@@ -4569,10 +4708,10 @@ var some = doParallel(_createTester(Boolean, identity));
4569
4708
  * @category Collection
4570
4709
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4571
4710
  * @param {number} limit - The maximum number of async operations at a time.
4572
- * @param {Function} iteratee - A truth test to apply to each item in the array
4573
- * in parallel. The iteratee is passed a `callback(err, truthValue)` which must
4574
- * be called with a boolean argument once it has completed. Invoked with
4575
- * (item, callback).
4711
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4712
+ * in the collections in parallel.
4713
+ * The iteratee should complete with a boolean `result` value.
4714
+ * Invoked with (item, callback).
4576
4715
  * @param {Function} [callback] - A callback which is called as soon as any
4577
4716
  * iteratee returns `true`, or after all the iteratee functions have finished.
4578
4717
  * Result will be either `true` or `false` depending on the values of the async
@@ -4591,10 +4730,10 @@ var someLimit = doParallelLimit(_createTester(Boolean, identity));
4591
4730
  * @alias anySeries
4592
4731
  * @category Collection
4593
4732
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4594
- * @param {Function} iteratee - A truth test to apply to each item in the array
4595
- * in parallel. The iteratee is passed a `callback(err, truthValue)` which must
4596
- * be called with a boolean argument once it has completed. Invoked with
4597
- * (item, callback).
4733
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4734
+ * in the collections in series.
4735
+ * The iteratee should complete with a boolean `result` value.
4736
+ * Invoked with (item, callback).
4598
4737
  * @param {Function} [callback] - A callback which is called as soon as any
4599
4738
  * iteratee returns `true`, or after all the iteratee functions have finished.
4600
4739
  * Result will be either `true` or `false` depending on the values of the async
@@ -4612,10 +4751,11 @@ var someSeries = doLimit(someLimit, 1);
4612
4751
  * @method
4613
4752
  * @category Collection
4614
4753
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4615
- * @param {Function} iteratee - A function to apply to each item in `coll`.
4616
- * The iteratee is passed a `callback(err, sortValue)` which must be called once
4617
- * it has completed with an error (which can be `null`) and a value to use as
4618
- * the sort criteria. Invoked with (item, callback).
4754
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
4755
+ * `coll`.
4756
+ * The iteratee should complete with a value to use as the sort criteria as
4757
+ * its `result`.
4758
+ * Invoked with (item, callback).
4619
4759
  * @param {Function} callback - A callback which is called after all the
4620
4760
  * `iteratee` functions have finished, or an error occurs. Results is the items
4621
4761
  * from the original `coll` sorted by the values returned by the `iteratee`
@@ -4649,8 +4789,9 @@ var someSeries = doLimit(someLimit, 1);
4649
4789
  * });
4650
4790
  */
4651
4791
  function sortBy(coll, iteratee, callback) {
4792
+ var _iteratee = wrapAsync$1(iteratee);
4652
4793
  map(coll, function (x, callback) {
4653
- iteratee(x, function (err, criteria) {
4794
+ _iteratee(x, function (err, criteria) {
4654
4795
  if (err) return callback(err);
4655
4796
  callback(null, { value: x, criteria: criteria });
4656
4797
  });
@@ -4676,14 +4817,13 @@ function sortBy(coll, iteratee, callback) {
4676
4817
  * @memberOf module:Utils
4677
4818
  * @method
4678
4819
  * @category Util
4679
- * @param {Function} asyncFn - The asynchronous function you want to set the
4680
- * time limit.
4820
+ * @param {AsyncFunction} asyncFn - The async function to limit in time.
4681
4821
  * @param {number} milliseconds - The specified time limit.
4682
4822
  * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
4683
4823
  * to timeout Error for more information..
4684
- * @returns {Function} Returns a wrapped function that can be used with any of
4685
- * the control flow functions. Invoke this function with the same
4686
- * parameters as you would `asyncFunc`.
4824
+ * @returns {AsyncFunction} Returns a wrapped function that can be used with any
4825
+ * of the control flow functions.
4826
+ * Invoke this function with the same parameters as you would `asyncFunc`.
4687
4827
  * @example
4688
4828
  *
4689
4829
  * function myFunction(foo, callback) {
@@ -4730,11 +4870,13 @@ function timeout(asyncFn, milliseconds, info) {
4730
4870
  originalCallback(error);
4731
4871
  }
4732
4872
 
4873
+ var fn = wrapAsync$1(asyncFn);
4874
+
4733
4875
  return initialParams(function (args, origCallback) {
4734
4876
  originalCallback = origCallback;
4735
4877
  // setup timer and call original function
4736
4878
  timer = setTimeout(timeoutCallback, milliseconds);
4737
- asyncFn.apply(null, args.concat(injectedCallback));
4879
+ fn.apply(null, args.concat(injectedCallback));
4738
4880
  });
4739
4881
  }
4740
4882
 
@@ -4777,12 +4919,13 @@ function baseRange(start, end, step, fromRight) {
4777
4919
  * @category Control Flow
4778
4920
  * @param {number} count - The number of times to run the function.
4779
4921
  * @param {number} limit - The maximum number of async operations at a time.
4780
- * @param {Function} iteratee - The function to call `n` times. Invoked with the
4781
- * iteration index and a callback (n, next).
4922
+ * @param {AsyncFunction} iteratee - The async function to call `n` times.
4923
+ * Invoked with the iteration index and a callback: (n, next).
4782
4924
  * @param {Function} callback - see [async.map]{@link module:Collections.map}.
4783
4925
  */
4784
4926
  function timeLimit(count, limit, iteratee, callback) {
4785
- mapLimit(baseRange(0, count, 1), limit, iteratee, callback);
4927
+ var _iteratee = wrapAsync$1(iteratee);
4928
+ mapLimit(baseRange(0, count, 1), limit, _iteratee, callback);
4786
4929
  }
4787
4930
 
4788
4931
  /**
@@ -4796,8 +4939,8 @@ function timeLimit(count, limit, iteratee, callback) {
4796
4939
  * @see [async.map]{@link module:Collections.map}
4797
4940
  * @category Control Flow
4798
4941
  * @param {number} n - The number of times to run the function.
4799
- * @param {Function} iteratee - The function to call `n` times. Invoked with the
4800
- * iteration index and a callback (n, next).
4942
+ * @param {AsyncFunction} iteratee - The async function to call `n` times.
4943
+ * Invoked with the iteration index and a callback: (n, next).
4801
4944
  * @param {Function} callback - see {@link module:Collections.map}.
4802
4945
  * @example
4803
4946
  *
@@ -4829,8 +4972,8 @@ var times = doLimit(timeLimit, Infinity);
4829
4972
  * @see [async.times]{@link module:ControlFlow.times}
4830
4973
  * @category Control Flow
4831
4974
  * @param {number} n - The number of times to run the function.
4832
- * @param {Function} iteratee - The function to call `n` times. Invoked with the
4833
- * iteration index and a callback (n, next).
4975
+ * @param {AsyncFunction} iteratee - The async function to call `n` times.
4976
+ * Invoked with the iteration index and a callback: (n, next).
4834
4977
  * @param {Function} callback - see {@link module:Collections.map}.
4835
4978
  */
4836
4979
  var timesSeries = doLimit(timeLimit, 1);
@@ -4848,11 +4991,8 @@ var timesSeries = doLimit(timeLimit, 1);
4848
4991
  * @param {Array|Iterable|Object} coll - A collection to iterate over.
4849
4992
  * @param {*} [accumulator] - The initial state of the transform. If omitted,
4850
4993
  * it will default to an empty Object or Array, depending on the type of `coll`
4851
- * @param {Function} iteratee - A function applied to each item in the
4852
- * collection that potentially modifies the accumulator. The `iteratee` is
4853
- * passed a `callback(err)` which accepts an optional error as its first
4854
- * argument. If an error is passed to the callback, the transform is stopped
4855
- * and the main `callback` is immediately called with the error.
4994
+ * @param {AsyncFunction} iteratee - A function applied to each item in the
4995
+ * collection that potentially modifies the accumulator.
4856
4996
  * Invoked with (accumulator, item, key, callback).
4857
4997
  * @param {Function} [callback] - A callback which is called after all the
4858
4998
  * `iteratee` functions have finished. Result is the transformed accumulator.
@@ -4881,15 +5021,16 @@ var timesSeries = doLimit(timeLimit, 1);
4881
5021
  * })
4882
5022
  */
4883
5023
  function transform(coll, accumulator, iteratee, callback) {
4884
- if (arguments.length === 3) {
5024
+ if (arguments.length <= 3) {
4885
5025
  callback = iteratee;
4886
5026
  iteratee = accumulator;
4887
5027
  accumulator = isArray(coll) ? [] : {};
4888
5028
  }
4889
5029
  callback = once(callback || noop);
5030
+ var _iteratee = wrapAsync$1(iteratee);
4890
5031
 
4891
5032
  eachOf(coll, function (v, k, cb) {
4892
- iteratee(accumulator, v, k, cb);
5033
+ _iteratee(accumulator, v, k, cb);
4893
5034
  }, function (err) {
4894
5035
  callback(err, accumulator);
4895
5036
  });
@@ -4905,8 +5046,8 @@ function transform(coll, accumulator, iteratee, callback) {
4905
5046
  * @method
4906
5047
  * @see [async.memoize]{@link module:Utils.memoize}
4907
5048
  * @category Util
4908
- * @param {Function} fn - the memoized function
4909
- * @returns {Function} a function that calls the original unmemoized function
5049
+ * @param {AsyncFunction} fn - the memoized function
5050
+ * @returns {AsyncFunction} a function that calls the original unmemoized function
4910
5051
  */
4911
5052
  function unmemoize(fn) {
4912
5053
  return function () {
@@ -4925,9 +5066,8 @@ function unmemoize(fn) {
4925
5066
  * @category Control Flow
4926
5067
  * @param {Function} test - synchronous truth test to perform before each
4927
5068
  * execution of `iteratee`. Invoked with ().
4928
- * @param {Function} iteratee - A function which is called each time `test` passes.
4929
- * The function is passed a `callback(err)`, which must be called once it has
4930
- * completed with an optional `err` argument. Invoked with (callback).
5069
+ * @param {AsyncFunction} iteratee - An async function which is called each time
5070
+ * `test` passes. Invoked with (callback).
4931
5071
  * @param {Function} [callback] - A callback which is called after the test
4932
5072
  * function has failed and repeated execution of `iteratee` has stopped. `callback`
4933
5073
  * will be passed an error and any arguments passed to the final `iteratee`'s
@@ -4951,19 +5091,20 @@ function unmemoize(fn) {
4951
5091
  */
4952
5092
  function whilst(test, iteratee, callback) {
4953
5093
  callback = onlyOnce(callback || noop);
5094
+ var _iteratee = wrapAsync$1(iteratee);
4954
5095
  if (!test()) return callback(null);
4955
5096
  var next = rest(function (err, args) {
4956
5097
  if (err) return callback(err);
4957
- if (test()) return iteratee(next);
5098
+ if (test()) return _iteratee(next);
4958
5099
  callback.apply(null, [null].concat(args));
4959
5100
  });
4960
- iteratee(next);
5101
+ _iteratee(next);
4961
5102
  }
4962
5103
 
4963
5104
  /**
4964
- * Repeatedly call `fn` until `test` returns `true`. Calls `callback` when
5105
+ * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
4965
5106
  * stopped, or an error occurs. `callback` will be passed an error and any
4966
- * arguments passed to the final `fn`'s callback.
5107
+ * arguments passed to the final `iteratee`'s callback.
4967
5108
  *
4968
5109
  * The inverse of [whilst]{@link module:ControlFlow.whilst}.
4969
5110
  *
@@ -4974,19 +5115,18 @@ function whilst(test, iteratee, callback) {
4974
5115
  * @see [async.whilst]{@link module:ControlFlow.whilst}
4975
5116
  * @category Control Flow
4976
5117
  * @param {Function} test - synchronous truth test to perform before each
4977
- * execution of `fn`. Invoked with ().
4978
- * @param {Function} fn - A function which is called each time `test` fails.
4979
- * The function is passed a `callback(err)`, which must be called once it has
4980
- * completed with an optional `err` argument. Invoked with (callback).
5118
+ * execution of `iteratee`. Invoked with ().
5119
+ * @param {AsyncFunction} iteratee - An async function which is called each time
5120
+ * `test` fails. Invoked with (callback).
4981
5121
  * @param {Function} [callback] - A callback which is called after the test
4982
- * function has passed and repeated execution of `fn` has stopped. `callback`
4983
- * will be passed an error and any arguments passed to the final `fn`'s
5122
+ * function has passed and repeated execution of `iteratee` has stopped. `callback`
5123
+ * will be passed an error and any arguments passed to the final `iteratee`'s
4984
5124
  * callback. Invoked with (err, [results]);
4985
5125
  */
4986
- function until(test, fn, callback) {
5126
+ function until(test, iteratee, callback) {
4987
5127
  whilst(function () {
4988
5128
  return !test.apply(this, arguments);
4989
- }, fn, callback);
5129
+ }, iteratee, callback);
4990
5130
  }
4991
5131
 
4992
5132
  /**
@@ -5000,10 +5140,10 @@ function until(test, fn, callback) {
5000
5140
  * @memberOf module:ControlFlow
5001
5141
  * @method
5002
5142
  * @category Control Flow
5003
- * @param {Array} tasks - An array of functions to run, each function is passed
5004
- * a `callback(err, result1, result2, ...)` it must call on completion. The
5005
- * first argument is an error (which can be `null`) and any further arguments
5006
- * will be passed as arguments in order to the next task.
5143
+ * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
5144
+ * to run.
5145
+ * Each function should complete with any number of `result` values.
5146
+ * The `result` values will be passed as arguments, in order, to the next task.
5007
5147
  * @param {Function} [callback] - An optional callback to run once all the
5008
5148
  * functions have completed. This will be passed the results of the last task's
5009
5149
  * callback. Invoked with (err, [results]).
@@ -5066,19 +5206,59 @@ var waterfall = function (tasks, callback) {
5066
5206
 
5067
5207
  args.push(taskCallback);
5068
5208
 
5069
- var task = tasks[taskIndex++];
5209
+ var task = wrapAsync$1(tasks[taskIndex++]);
5070
5210
  task.apply(null, args);
5071
5211
  }
5072
5212
 
5073
5213
  nextTask([]);
5074
5214
  };
5075
5215
 
5216
+ /**
5217
+ * An "async function" in the context of Async is an asynchronous function with
5218
+ * a variable number of parameters, with the final parameter being a callback.
5219
+ * (`function (arg1, arg2, ..., callback) {}`)
5220
+ * The final callback is of the form `callback(err, results...)`, which must be
5221
+ * called once the function is completed. The callback should be called with a
5222
+ * Error as its first argument to signal that an error occurred.
5223
+ * Otherwise, if no error occurred, it should be called with `null` as the first
5224
+ * argument, and any additional `result` arguments that may apply, to signal
5225
+ * successful completion.
5226
+ * The callback must be called exactly once, ideally on a later tick of the
5227
+ * JavaScript event loop.
5228
+ *
5229
+ * This type of function is also referred to as a "Node-style async function",
5230
+ * or a "continuation passing-style function" (CPS). Most of the methods of this
5231
+ * library are themselves CPS/Node-style async functions, or functions that
5232
+ * return CPS/Node-style async functions.
5233
+ *
5234
+ * Wherever we accept a Node-style async function, we also directly accept an
5235
+ * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
5236
+ * In this case, the `async` function will not be passed a final callback
5237
+ * argument, and any thrown error will be used as the `err` argument of the
5238
+ * implicit callback, and the return value will be used as the `result` value.
5239
+ * (i.e. a `rejected` of the returned Promise becomes the `err` callback
5240
+ * argument, and a `resolved` value becomes the `result`.)
5241
+ *
5242
+ * Note, due to JavaScript limitations, we can only detect native `async`
5243
+ * functions and not transpilied implementations.
5244
+ * Your environment must have `async`/`await` support for this to work.
5245
+ * (e.g. Node > v7.6, or a recent version of a modern browser).
5246
+ * If you are using `async` functions through a transpiler (e.g. Babel), you
5247
+ * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
5248
+ * because the `async function` will be compiled to an ordinary function that
5249
+ * returns a promise.
5250
+ *
5251
+ * @typedef {Function} AsyncFunction
5252
+ * @static
5253
+ */
5254
+
5076
5255
  /**
5077
5256
  * Async is a utility module which provides straight-forward, powerful functions
5078
5257
  * for working with asynchronous JavaScript. Although originally designed for
5079
5258
  * use with [Node.js](http://nodejs.org) and installable via
5080
5259
  * `npm install --save async`, it can also be used directly in the browser.
5081
5260
  * @module async
5261
+ * @see AsyncFunction
5082
5262
  */
5083
5263
 
5084
5264
  /**
@@ -5096,6 +5276,7 @@ var waterfall = function (tasks, callback) {
5096
5276
  * A collection of `async` utility functions.
5097
5277
  * @module Utils
5098
5278
  */
5279
+
5099
5280
  var index = {
5100
5281
  applyEach: applyEach,
5101
5282
  applyEachSeries: applyEachSeries,
@@ -5130,6 +5311,9 @@ var index = {
5130
5311
  filterLimit: filterLimit,
5131
5312
  filterSeries: filterSeries,
5132
5313
  forever: forever,
5314
+ groupBy: groupBy,
5315
+ groupByLimit: groupByLimit,
5316
+ groupBySeries: groupBySeries,
5133
5317
  log: log,
5134
5318
  map: map,
5135
5319
  mapLimit: mapLimit,
@@ -5222,6 +5406,9 @@ exports.filter = filter;
5222
5406
  exports.filterLimit = filterLimit;
5223
5407
  exports.filterSeries = filterSeries;
5224
5408
  exports.forever = forever;
5409
+ exports.groupBy = groupBy;
5410
+ exports.groupByLimit = groupByLimit;
5411
+ exports.groupBySeries = groupBySeries;
5225
5412
  exports.log = log;
5226
5413
  exports.map = map;
5227
5414
  exports.mapLimit = mapLimit;