source: frontend/node_modules/async/dist/async.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

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