Path: blob/master/node_modules/async/dist/async.mjs
2490 views
/**1* Creates a continuation function with some arguments already applied.2*3* Useful as a shorthand when combined with other control flow functions. Any4* arguments passed to the returned function are added to the arguments5* originally passed to apply.6*7* @name apply8* @static9* @memberOf module:Utils10* @method11* @category Util12* @param {Function} fn - The function you want to eventually apply all13* arguments to. Invokes with (arguments...).14* @param {...*} arguments... - Any number of arguments to automatically apply15* when the continuation is called.16* @returns {Function} the partially-applied function17* @example18*19* // using apply20* async.parallel([21* async.apply(fs.writeFile, 'testfile1', 'test1'),22* async.apply(fs.writeFile, 'testfile2', 'test2')23* ]);24*25*26* // the same process without using apply27* async.parallel([28* function(callback) {29* fs.writeFile('testfile1', 'test1', callback);30* },31* function(callback) {32* fs.writeFile('testfile2', 'test2', callback);33* }34* ]);35*36* // It's possible to pass any number of additional arguments when calling the37* // continuation:38*39* node> var fn = async.apply(sys.puts, 'one');40* node> fn('two', 'three');41* one42* two43* three44*/45function apply(fn, ...args) {46return (...callArgs) => fn(...args,...callArgs);47}4849function initialParams (fn) {50return function (...args/*, callback*/) {51var callback = args.pop();52return fn.call(this, args, callback);53};54}5556/* istanbul ignore file */5758var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;59var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;60var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';6162function fallback(fn) {63setTimeout(fn, 0);64}6566function wrap(defer) {67return (fn, ...args) => defer(() => fn(...args));68}6970var _defer;7172if (hasQueueMicrotask) {73_defer = queueMicrotask;74} else if (hasSetImmediate) {75_defer = setImmediate;76} else if (hasNextTick) {77_defer = process.nextTick;78} else {79_defer = fallback;80}8182var setImmediate$1 = wrap(_defer);8384/**85* Take a sync function and make it async, passing its return value to a86* callback. This is useful for plugging sync functions into a waterfall,87* series, or other async functions. Any arguments passed to the generated88* function will be passed to the wrapped function (except for the final89* callback argument). Errors thrown will be passed to the callback.90*91* If the function passed to `asyncify` returns a Promise, that promises's92* resolved/rejected state will be used to call the callback, rather than simply93* the synchronous return value.94*95* This also means you can asyncify ES2017 `async` functions.96*97* @name asyncify98* @static99* @memberOf module:Utils100* @method101* @alias wrapSync102* @category Util103* @param {Function} func - The synchronous function, or Promise-returning104* function to convert to an {@link AsyncFunction}.105* @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be106* invoked with `(args..., callback)`.107* @example108*109* // passing a regular synchronous function110* async.waterfall([111* async.apply(fs.readFile, filename, "utf8"),112* async.asyncify(JSON.parse),113* function (data, next) {114* // data is the result of parsing the text.115* // If there was a parsing error, it would have been caught.116* }117* ], callback);118*119* // passing a function returning a promise120* async.waterfall([121* async.apply(fs.readFile, filename, "utf8"),122* async.asyncify(function (contents) {123* return db.model.create(contents);124* }),125* function (model, next) {126* // `model` is the instantiated model object.127* // If there was an error, this function would be skipped.128* }129* ], callback);130*131* // es2017 example, though `asyncify` is not needed if your JS environment132* // supports async functions out of the box133* var q = async.queue(async.asyncify(async function(file) {134* var intermediateStep = await processFile(file);135* return await somePromise(intermediateStep)136* }));137*138* q.push(files);139*/140function asyncify(func) {141if (isAsync(func)) {142return function (...args/*, callback*/) {143const callback = args.pop();144const promise = func.apply(this, args);145return handlePromise(promise, callback)146}147}148149return initialParams(function (args, callback) {150var result;151try {152result = func.apply(this, args);153} catch (e) {154return callback(e);155}156// if result is Promise object157if (result && typeof result.then === 'function') {158return handlePromise(result, callback)159} else {160callback(null, result);161}162});163}164165function handlePromise(promise, callback) {166return promise.then(value => {167invokeCallback(callback, null, value);168}, err => {169invokeCallback(callback, err && err.message ? err : new Error(err));170});171}172173function invokeCallback(callback, error, value) {174try {175callback(error, value);176} catch (err) {177setImmediate$1(e => { throw e }, err);178}179}180181function isAsync(fn) {182return fn[Symbol.toStringTag] === 'AsyncFunction';183}184185function isAsyncGenerator(fn) {186return fn[Symbol.toStringTag] === 'AsyncGenerator';187}188189function isAsyncIterable(obj) {190return typeof obj[Symbol.asyncIterator] === 'function';191}192193function wrapAsync(asyncFn) {194if (typeof asyncFn !== 'function') throw new Error('expected a function')195return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;196}197198// conditionally promisify a function.199// only return a promise if a callback is omitted200function awaitify (asyncFn, arity = asyncFn.length) {201if (!arity) throw new Error('arity is undefined')202function awaitable (...args) {203if (typeof args[arity - 1] === 'function') {204return asyncFn.apply(this, args)205}206207return new Promise((resolve, reject) => {208args[arity - 1] = (err, ...cbArgs) => {209if (err) return reject(err)210resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);211};212asyncFn.apply(this, args);213})214}215216return awaitable217}218219function applyEach (eachfn) {220return function applyEach(fns, ...callArgs) {221const go = awaitify(function (callback) {222var that = this;223return eachfn(fns, (fn, cb) => {224wrapAsync(fn).apply(that, callArgs.concat(cb));225}, callback);226});227return go;228};229}230231function _asyncMap(eachfn, arr, iteratee, callback) {232arr = arr || [];233var results = [];234var counter = 0;235var _iteratee = wrapAsync(iteratee);236237return eachfn(arr, (value, _, iterCb) => {238var index = counter++;239_iteratee(value, (err, v) => {240results[index] = v;241iterCb(err);242});243}, err => {244callback(err, results);245});246}247248function isArrayLike(value) {249return value &&250typeof value.length === 'number' &&251value.length >= 0 &&252value.length % 1 === 0;253}254255// A temporary value used to identify if the loop should be broken.256// See #1064, #1293257const breakLoop = {};258259function once(fn) {260function wrapper (...args) {261if (fn === null) return;262var callFn = fn;263fn = null;264callFn.apply(this, args);265}266Object.assign(wrapper, fn);267return wrapper268}269270function getIterator (coll) {271return coll[Symbol.iterator] && coll[Symbol.iterator]();272}273274function createArrayIterator(coll) {275var i = -1;276var len = coll.length;277return function next() {278return ++i < len ? {value: coll[i], key: i} : null;279}280}281282function createES2015Iterator(iterator) {283var i = -1;284return function next() {285var item = iterator.next();286if (item.done)287return null;288i++;289return {value: item.value, key: i};290}291}292293function createObjectIterator(obj) {294var okeys = obj ? Object.keys(obj) : [];295var i = -1;296var len = okeys.length;297return function next() {298var key = okeys[++i];299if (key === '__proto__') {300return next();301}302return i < len ? {value: obj[key], key} : null;303};304}305306function createIterator(coll) {307if (isArrayLike(coll)) {308return createArrayIterator(coll);309}310311var iterator = getIterator(coll);312return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);313}314315function onlyOnce(fn) {316return function (...args) {317if (fn === null) throw new Error("Callback was already called.");318var callFn = fn;319fn = null;320callFn.apply(this, args);321};322}323324// for async generators325function asyncEachOfLimit(generator, limit, iteratee, callback) {326let done = false;327let canceled = false;328let awaiting = false;329let running = 0;330let idx = 0;331332function replenish() {333//console.log('replenish')334if (running >= limit || awaiting || done) return335//console.log('replenish awaiting')336awaiting = true;337generator.next().then(({value, done: iterDone}) => {338//console.log('got value', value)339if (canceled || done) return340awaiting = false;341if (iterDone) {342done = true;343if (running <= 0) {344//console.log('done nextCb')345callback(null);346}347return;348}349running++;350iteratee(value, idx, iterateeCallback);351idx++;352replenish();353}).catch(handleError);354}355356function iterateeCallback(err, result) {357//console.log('iterateeCallback')358running -= 1;359if (canceled) return360if (err) return handleError(err)361362if (err === false) {363done = true;364canceled = true;365return366}367368if (result === breakLoop || (done && running <= 0)) {369done = true;370//console.log('done iterCb')371return callback(null);372}373replenish();374}375376function handleError(err) {377if (canceled) return378awaiting = false;379done = true;380callback(err);381}382383replenish();384}385386var eachOfLimit = (limit) => {387return (obj, iteratee, callback) => {388callback = once(callback);389if (limit <= 0) {390throw new RangeError('concurrency limit cannot be less than 1')391}392if (!obj) {393return callback(null);394}395if (isAsyncGenerator(obj)) {396return asyncEachOfLimit(obj, limit, iteratee, callback)397}398if (isAsyncIterable(obj)) {399return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)400}401var nextElem = createIterator(obj);402var done = false;403var canceled = false;404var running = 0;405var looping = false;406407function iterateeCallback(err, value) {408if (canceled) return409running -= 1;410if (err) {411done = true;412callback(err);413}414else if (err === false) {415done = true;416canceled = true;417}418else if (value === breakLoop || (done && running <= 0)) {419done = true;420return callback(null);421}422else if (!looping) {423replenish();424}425}426427function replenish () {428looping = true;429while (running < limit && !done) {430var elem = nextElem();431if (elem === null) {432done = true;433if (running <= 0) {434callback(null);435}436return;437}438running += 1;439iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));440}441looping = false;442}443444replenish();445};446};447448/**449* The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a450* time.451*452* @name eachOfLimit453* @static454* @memberOf module:Collections455* @method456* @see [async.eachOf]{@link module:Collections.eachOf}457* @alias forEachOfLimit458* @category Collection459* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.460* @param {number} limit - The maximum number of async operations at a time.461* @param {AsyncFunction} iteratee - An async function to apply to each462* item in `coll`. The `key` is the item's key, or index in the case of an463* array.464* Invoked with (item, key, callback).465* @param {Function} [callback] - A callback which is called when all466* `iteratee` functions have finished, or an error occurs. Invoked with (err).467* @returns {Promise} a promise, if a callback is omitted468*/469function eachOfLimit$1(coll, limit, iteratee, callback) {470return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);471}472473var eachOfLimit$2 = awaitify(eachOfLimit$1, 4);474475// eachOf implementation optimized for array-likes476function eachOfArrayLike(coll, iteratee, callback) {477callback = once(callback);478var index = 0,479completed = 0,480{length} = coll,481canceled = false;482if (length === 0) {483callback(null);484}485486function iteratorCallback(err, value) {487if (err === false) {488canceled = true;489}490if (canceled === true) return491if (err) {492callback(err);493} else if ((++completed === length) || value === breakLoop) {494callback(null);495}496}497498for (; index < length; index++) {499iteratee(coll[index], index, onlyOnce(iteratorCallback));500}501}502503// a generic version of eachOf which can handle array, object, and iterator cases.504function eachOfGeneric (coll, iteratee, callback) {505return eachOfLimit$2(coll, Infinity, iteratee, callback);506}507508/**509* Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument510* to the iteratee.511*512* @name eachOf513* @static514* @memberOf module:Collections515* @method516* @alias forEachOf517* @category Collection518* @see [async.each]{@link module:Collections.each}519* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.520* @param {AsyncFunction} iteratee - A function to apply to each521* item in `coll`.522* The `key` is the item's key, or index in the case of an array.523* Invoked with (item, key, callback).524* @param {Function} [callback] - A callback which is called when all525* `iteratee` functions have finished, or an error occurs. Invoked with (err).526* @returns {Promise} a promise, if a callback is omitted527* @example528*529* // dev.json is a file containing a valid json object config for dev environment530* // dev.json is a file containing a valid json object config for test environment531* // prod.json is a file containing a valid json object config for prod environment532* // invalid.json is a file with a malformed json object533*534* let configs = {}; //global variable535* let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};536* let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};537*538* // asynchronous function that reads a json file and parses the contents as json object539* function parseFile(file, key, callback) {540* fs.readFile(file, "utf8", function(err, data) {541* if (err) return calback(err);542* try {543* configs[key] = JSON.parse(data);544* } catch (e) {545* return callback(e);546* }547* callback();548* });549* }550*551* // Using callbacks552* async.forEachOf(validConfigFileMap, parseFile, function (err) {553* if (err) {554* console.error(err);555* } else {556* console.log(configs);557* // configs is now a map of JSON data, e.g.558* // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}559* }560* });561*562* //Error handing563* async.forEachOf(invalidConfigFileMap, parseFile, function (err) {564* if (err) {565* console.error(err);566* // JSON parse error exception567* } else {568* console.log(configs);569* }570* });571*572* // Using Promises573* async.forEachOf(validConfigFileMap, parseFile)574* .then( () => {575* console.log(configs);576* // configs is now a map of JSON data, e.g.577* // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}578* }).catch( err => {579* console.error(err);580* });581*582* //Error handing583* async.forEachOf(invalidConfigFileMap, parseFile)584* .then( () => {585* console.log(configs);586* }).catch( err => {587* console.error(err);588* // JSON parse error exception589* });590*591* // Using async/await592* async () => {593* try {594* let result = await async.forEachOf(validConfigFileMap, parseFile);595* console.log(configs);596* // configs is now a map of JSON data, e.g.597* // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}598* }599* catch (err) {600* console.log(err);601* }602* }603*604* //Error handing605* async () => {606* try {607* let result = await async.forEachOf(invalidConfigFileMap, parseFile);608* console.log(configs);609* }610* catch (err) {611* console.log(err);612* // JSON parse error exception613* }614* }615*616*/617function eachOf(coll, iteratee, callback) {618var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;619return eachOfImplementation(coll, wrapAsync(iteratee), callback);620}621622var eachOf$1 = awaitify(eachOf, 3);623624/**625* Produces a new collection of values by mapping each value in `coll` through626* the `iteratee` function. The `iteratee` is called with an item from `coll`627* and a callback for when it has finished processing. Each of these callbacks628* takes 2 arguments: an `error`, and the transformed item from `coll`. If629* `iteratee` passes an error to its callback, the main `callback` (for the630* `map` function) is immediately called with the error.631*632* Note, that since this function applies the `iteratee` to each item in633* parallel, there is no guarantee that the `iteratee` functions will complete634* in order. However, the results array will be in the same order as the635* original `coll`.636*637* If `map` is passed an Object, the results will be an Array. The results638* will roughly be in the order of the original Objects' keys (but this can639* vary across JavaScript engines).640*641* @name map642* @static643* @memberOf module:Collections644* @method645* @category Collection646* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.647* @param {AsyncFunction} iteratee - An async function to apply to each item in648* `coll`.649* The iteratee should complete with the transformed item.650* Invoked with (item, callback).651* @param {Function} [callback] - A callback which is called when all `iteratee`652* functions have finished, or an error occurs. Results is an Array of the653* transformed items from the `coll`. Invoked with (err, results).654* @returns {Promise} a promise, if no callback is passed655* @example656*657* // file1.txt is a file that is 1000 bytes in size658* // file2.txt is a file that is 2000 bytes in size659* // file3.txt is a file that is 3000 bytes in size660* // file4.txt does not exist661*662* const fileList = ['file1.txt','file2.txt','file3.txt'];663* const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];664*665* // asynchronous function that returns the file size in bytes666* function getFileSizeInBytes(file, callback) {667* fs.stat(file, function(err, stat) {668* if (err) {669* return callback(err);670* }671* callback(null, stat.size);672* });673* }674*675* // Using callbacks676* async.map(fileList, getFileSizeInBytes, function(err, results) {677* if (err) {678* console.log(err);679* } else {680* console.log(results);681* // results is now an array of the file size in bytes for each file, e.g.682* // [ 1000, 2000, 3000]683* }684* });685*686* // Error Handling687* async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {688* if (err) {689* console.log(err);690* // [ Error: ENOENT: no such file or directory ]691* } else {692* console.log(results);693* }694* });695*696* // Using Promises697* async.map(fileList, getFileSizeInBytes)698* .then( results => {699* console.log(results);700* // results is now an array of the file size in bytes for each file, e.g.701* // [ 1000, 2000, 3000]702* }).catch( err => {703* console.log(err);704* });705*706* // Error Handling707* async.map(withMissingFileList, getFileSizeInBytes)708* .then( results => {709* console.log(results);710* }).catch( err => {711* console.log(err);712* // [ Error: ENOENT: no such file or directory ]713* });714*715* // Using async/await716* async () => {717* try {718* let results = await async.map(fileList, getFileSizeInBytes);719* console.log(results);720* // results is now an array of the file size in bytes for each file, e.g.721* // [ 1000, 2000, 3000]722* }723* catch (err) {724* console.log(err);725* }726* }727*728* // Error Handling729* async () => {730* try {731* let results = await async.map(withMissingFileList, getFileSizeInBytes);732* console.log(results);733* }734* catch (err) {735* console.log(err);736* // [ Error: ENOENT: no such file or directory ]737* }738* }739*740*/741function map (coll, iteratee, callback) {742return _asyncMap(eachOf$1, coll, iteratee, callback)743}744var map$1 = awaitify(map, 3);745746/**747* Applies the provided arguments to each function in the array, calling748* `callback` after all functions have completed. If you only provide the first749* argument, `fns`, then it will return a function which lets you pass in the750* arguments as if it were a single function call. If more arguments are751* provided, `callback` is required while `args` is still optional. The results752* for each of the applied async functions are passed to the final callback753* as an array.754*755* @name applyEach756* @static757* @memberOf module:ControlFlow758* @method759* @category Control Flow760* @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s761* to all call with the same arguments762* @param {...*} [args] - any number of separate arguments to pass to the763* function.764* @param {Function} [callback] - the final argument should be the callback,765* called when all functions have completed processing.766* @returns {AsyncFunction} - Returns a function that takes no args other than767* an optional callback, that is the result of applying the `args` to each768* of the functions.769* @example770*771* const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')772*773* appliedFn((err, results) => {774* // results[0] is the results for `enableSearch`775* // results[1] is the results for `updateSchema`776* });777*778* // partial application example:779* async.each(780* buckets,781* async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),782* callback783* );784*/785var applyEach$1 = applyEach(map$1);786787/**788* The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.789*790* @name eachOfSeries791* @static792* @memberOf module:Collections793* @method794* @see [async.eachOf]{@link module:Collections.eachOf}795* @alias forEachOfSeries796* @category Collection797* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.798* @param {AsyncFunction} iteratee - An async function to apply to each item in799* `coll`.800* Invoked with (item, key, callback).801* @param {Function} [callback] - A callback which is called when all `iteratee`802* functions have finished, or an error occurs. Invoked with (err).803* @returns {Promise} a promise, if a callback is omitted804*/805function eachOfSeries(coll, iteratee, callback) {806return eachOfLimit$2(coll, 1, iteratee, callback)807}808var eachOfSeries$1 = awaitify(eachOfSeries, 3);809810/**811* The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.812*813* @name mapSeries814* @static815* @memberOf module:Collections816* @method817* @see [async.map]{@link module:Collections.map}818* @category Collection819* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.820* @param {AsyncFunction} iteratee - An async function to apply to each item in821* `coll`.822* The iteratee should complete with the transformed item.823* Invoked with (item, callback).824* @param {Function} [callback] - A callback which is called when all `iteratee`825* functions have finished, or an error occurs. Results is an array of the826* transformed items from the `coll`. Invoked with (err, results).827* @returns {Promise} a promise, if no callback is passed828*/829function mapSeries (coll, iteratee, callback) {830return _asyncMap(eachOfSeries$1, coll, iteratee, callback)831}832var mapSeries$1 = awaitify(mapSeries, 3);833834/**835* The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.836*837* @name applyEachSeries838* @static839* @memberOf module:ControlFlow840* @method841* @see [async.applyEach]{@link module:ControlFlow.applyEach}842* @category Control Flow843* @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all844* call with the same arguments845* @param {...*} [args] - any number of separate arguments to pass to the846* function.847* @param {Function} [callback] - the final argument should be the callback,848* called when all functions have completed processing.849* @returns {AsyncFunction} - A function, that when called, is the result of850* appling the `args` to the list of functions. It takes no args, other than851* a callback.852*/853var applyEachSeries = applyEach(mapSeries$1);854855const PROMISE_SYMBOL = Symbol('promiseCallback');856857function promiseCallback () {858let resolve, reject;859function callback (err, ...args) {860if (err) return reject(err)861resolve(args.length > 1 ? args : args[0]);862}863864callback[PROMISE_SYMBOL] = new Promise((res, rej) => {865resolve = res,866reject = rej;867});868869return callback870}871872/**873* Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on874* their requirements. Each function can optionally depend on other functions875* being completed first, and each function is run as soon as its requirements876* are satisfied.877*878* If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence879* will stop. Further tasks will not execute (so any other functions depending880* on it will not run), and the main `callback` is immediately called with the881* error.882*883* {@link AsyncFunction}s also receive an object containing the results of functions which884* have completed so far as the first argument, if they have dependencies. If a885* task function has no dependencies, it will only be passed a callback.886*887* @name auto888* @static889* @memberOf module:ControlFlow890* @method891* @category Control Flow892* @param {Object} tasks - An object. Each of its properties is either a893* function or an array of requirements, with the {@link AsyncFunction} itself the last item894* in the array. The object's key of a property serves as the name of the task895* defined by that property, i.e. can be used when specifying requirements for896* other tasks. The function receives one or two arguments:897* * a `results` object, containing the results of the previously executed898* functions, only passed if the task has any dependencies,899* * a `callback(err, result)` function, which must be called when finished,900* passing an `error` (which can be `null`) and the result of the function's901* execution.902* @param {number} [concurrency=Infinity] - An optional `integer` for903* determining the maximum number of tasks that can be run in parallel. By904* default, as many as possible.905* @param {Function} [callback] - An optional callback which is called when all906* the tasks have been completed. It receives the `err` argument if any `tasks`907* pass an error to their callback. Results are always returned; however, if an908* error occurs, no further `tasks` will be performed, and the results object909* will only contain partial results. Invoked with (err, results).910* @returns {Promise} a promise, if a callback is not passed911* @example912*913* //Using Callbacks914* async.auto({915* get_data: function(callback) {916* // async code to get some data917* callback(null, 'data', 'converted to array');918* },919* make_folder: function(callback) {920* // async code to create a directory to store a file in921* // this is run at the same time as getting the data922* callback(null, 'folder');923* },924* write_file: ['get_data', 'make_folder', function(results, callback) {925* // once there is some data and the directory exists,926* // write the data to a file in the directory927* callback(null, 'filename');928* }],929* email_link: ['write_file', function(results, callback) {930* // once the file is written let's email a link to it...931* callback(null, {'file':results.write_file, 'email':'[email protected]'});932* }]933* }, function(err, results) {934* if (err) {935* console.log('err = ', err);936* }937* console.log('results = ', results);938* // results = {939* // get_data: ['data', 'converted to array']940* // make_folder; 'folder',941* // write_file: 'filename'942* // email_link: { file: 'filename', email: '[email protected]' }943* // }944* });945*946* //Using Promises947* async.auto({948* get_data: function(callback) {949* console.log('in get_data');950* // async code to get some data951* callback(null, 'data', 'converted to array');952* },953* make_folder: function(callback) {954* console.log('in make_folder');955* // async code to create a directory to store a file in956* // this is run at the same time as getting the data957* callback(null, 'folder');958* },959* write_file: ['get_data', 'make_folder', function(results, callback) {960* // once there is some data and the directory exists,961* // write the data to a file in the directory962* callback(null, 'filename');963* }],964* email_link: ['write_file', function(results, callback) {965* // once the file is written let's email a link to it...966* callback(null, {'file':results.write_file, 'email':'[email protected]'});967* }]968* }).then(results => {969* console.log('results = ', results);970* // results = {971* // get_data: ['data', 'converted to array']972* // make_folder; 'folder',973* // write_file: 'filename'974* // email_link: { file: 'filename', email: '[email protected]' }975* // }976* }).catch(err => {977* console.log('err = ', err);978* });979*980* //Using async/await981* async () => {982* try {983* let results = await async.auto({984* get_data: function(callback) {985* // async code to get some data986* callback(null, 'data', 'converted to array');987* },988* make_folder: function(callback) {989* // async code to create a directory to store a file in990* // this is run at the same time as getting the data991* callback(null, 'folder');992* },993* write_file: ['get_data', 'make_folder', function(results, callback) {994* // once there is some data and the directory exists,995* // write the data to a file in the directory996* callback(null, 'filename');997* }],998* email_link: ['write_file', function(results, callback) {999* // once the file is written let's email a link to it...1000* callback(null, {'file':results.write_file, 'email':'[email protected]'});1001* }]1002* });1003* console.log('results = ', results);1004* // results = {1005* // get_data: ['data', 'converted to array']1006* // make_folder; 'folder',1007* // write_file: 'filename'1008* // email_link: { file: 'filename', email: '[email protected]' }1009* // }1010* }1011* catch (err) {1012* console.log(err);1013* }1014* }1015*1016*/1017function auto(tasks, concurrency, callback) {1018if (typeof concurrency !== 'number') {1019// concurrency is optional, shift the args.1020callback = concurrency;1021concurrency = null;1022}1023callback = once(callback || promiseCallback());1024var numTasks = Object.keys(tasks).length;1025if (!numTasks) {1026return callback(null);1027}1028if (!concurrency) {1029concurrency = numTasks;1030}10311032var results = {};1033var runningTasks = 0;1034var canceled = false;1035var hasError = false;10361037var listeners = Object.create(null);10381039var readyTasks = [];10401041// for cycle detection:1042var readyToCheck = []; // tasks that have been identified as reachable1043// without the possibility of returning to an ancestor task1044var uncheckedDependencies = {};10451046Object.keys(tasks).forEach(key => {1047var task = tasks[key];1048if (!Array.isArray(task)) {1049// no dependencies1050enqueueTask(key, [task]);1051readyToCheck.push(key);1052return;1053}10541055var dependencies = task.slice(0, task.length - 1);1056var remainingDependencies = dependencies.length;1057if (remainingDependencies === 0) {1058enqueueTask(key, task);1059readyToCheck.push(key);1060return;1061}1062uncheckedDependencies[key] = remainingDependencies;10631064dependencies.forEach(dependencyName => {1065if (!tasks[dependencyName]) {1066throw new Error('async.auto task `' + key +1067'` has a non-existent dependency `' +1068dependencyName + '` in ' +1069dependencies.join(', '));1070}1071addListener(dependencyName, () => {1072remainingDependencies--;1073if (remainingDependencies === 0) {1074enqueueTask(key, task);1075}1076});1077});1078});10791080checkForDeadlocks();1081processQueue();10821083function enqueueTask(key, task) {1084readyTasks.push(() => runTask(key, task));1085}10861087function processQueue() {1088if (canceled) return1089if (readyTasks.length === 0 && runningTasks === 0) {1090return callback(null, results);1091}1092while(readyTasks.length && runningTasks < concurrency) {1093var run = readyTasks.shift();1094run();1095}10961097}10981099function addListener(taskName, fn) {1100var taskListeners = listeners[taskName];1101if (!taskListeners) {1102taskListeners = listeners[taskName] = [];1103}11041105taskListeners.push(fn);1106}11071108function taskComplete(taskName) {1109var taskListeners = listeners[taskName] || [];1110taskListeners.forEach(fn => fn());1111processQueue();1112}111311141115function runTask(key, task) {1116if (hasError) return;11171118var taskCallback = onlyOnce((err, ...result) => {1119runningTasks--;1120if (err === false) {1121canceled = true;1122return1123}1124if (result.length < 2) {1125[result] = result;1126}1127if (err) {1128var safeResults = {};1129Object.keys(results).forEach(rkey => {1130safeResults[rkey] = results[rkey];1131});1132safeResults[key] = result;1133hasError = true;1134listeners = Object.create(null);1135if (canceled) return1136callback(err, safeResults);1137} else {1138results[key] = result;1139taskComplete(key);1140}1141});11421143runningTasks++;1144var taskFn = wrapAsync(task[task.length - 1]);1145if (task.length > 1) {1146taskFn(results, taskCallback);1147} else {1148taskFn(taskCallback);1149}1150}11511152function checkForDeadlocks() {1153// Kahn's algorithm1154// https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm1155// http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html1156var currentTask;1157var counter = 0;1158while (readyToCheck.length) {1159currentTask = readyToCheck.pop();1160counter++;1161getDependents(currentTask).forEach(dependent => {1162if (--uncheckedDependencies[dependent] === 0) {1163readyToCheck.push(dependent);1164}1165});1166}11671168if (counter !== numTasks) {1169throw new Error(1170'async.auto cannot execute tasks due to a recursive dependency'1171);1172}1173}11741175function getDependents(taskName) {1176var result = [];1177Object.keys(tasks).forEach(key => {1178const task = tasks[key];1179if (Array.isArray(task) && task.indexOf(taskName) >= 0) {1180result.push(key);1181}1182});1183return result;1184}11851186return callback[PROMISE_SYMBOL]1187}11881189var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/;1190var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/;1191var FN_ARG_SPLIT = /,/;1192var FN_ARG = /(=.+)?(\s*)$/;11931194function stripComments(string) {1195let stripped = '';1196let index = 0;1197let endBlockComment = string.indexOf('*/');1198while (index < string.length) {1199if (string[index] === '/' && string[index+1] === '/') {1200// inline comment1201let endIndex = string.indexOf('\n', index);1202index = (endIndex === -1) ? string.length : endIndex;1203} else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) {1204// block comment1205let endIndex = string.indexOf('*/', index);1206if (endIndex !== -1) {1207index = endIndex + 2;1208endBlockComment = string.indexOf('*/', index);1209} else {1210stripped += string[index];1211index++;1212}1213} else {1214stripped += string[index];1215index++;1216}1217}1218return stripped;1219}12201221function parseParams(func) {1222const src = stripComments(func.toString());1223let match = src.match(FN_ARGS);1224if (!match) {1225match = src.match(ARROW_FN_ARGS);1226}1227if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src)1228let [, args] = match;1229return args1230.replace(/\s/g, '')1231.split(FN_ARG_SPLIT)1232.map((arg) => arg.replace(FN_ARG, '').trim());1233}12341235/**1236* A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent1237* tasks are specified as parameters to the function, after the usual callback1238* parameter, with the parameter names matching the names of the tasks it1239* depends on. This can provide even more readable task graphs which can be1240* easier to maintain.1241*1242* If a final callback is specified, the task results are similarly injected,1243* specified as named parameters after the initial error parameter.1244*1245* The autoInject function is purely syntactic sugar and its semantics are1246* otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.1247*1248* @name autoInject1249* @static1250* @memberOf module:ControlFlow1251* @method1252* @see [async.auto]{@link module:ControlFlow.auto}1253* @category Control Flow1254* @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of1255* the form 'func([dependencies...], callback). The object's key of a property1256* serves as the name of the task defined by that property, i.e. can be used1257* when specifying requirements for other tasks.1258* * The `callback` parameter is a `callback(err, result)` which must be called1259* when finished, passing an `error` (which can be `null`) and the result of1260* the function's execution. The remaining parameters name other tasks on1261* which the task is dependent, and the results from those tasks are the1262* arguments of those parameters.1263* @param {Function} [callback] - An optional callback which is called when all1264* the tasks have been completed. It receives the `err` argument if any `tasks`1265* pass an error to their callback, and a `results` object with any completed1266* task results, similar to `auto`.1267* @returns {Promise} a promise, if no callback is passed1268* @example1269*1270* // The example from `auto` can be rewritten as follows:1271* async.autoInject({1272* get_data: function(callback) {1273* // async code to get some data1274* callback(null, 'data', 'converted to array');1275* },1276* make_folder: function(callback) {1277* // async code to create a directory to store a file in1278* // this is run at the same time as getting the data1279* callback(null, 'folder');1280* },1281* write_file: function(get_data, make_folder, callback) {1282* // once there is some data and the directory exists,1283* // write the data to a file in the directory1284* callback(null, 'filename');1285* },1286* email_link: function(write_file, callback) {1287* // once the file is written let's email a link to it...1288* // write_file contains the filename returned by write_file.1289* callback(null, {'file':write_file, 'email':'[email protected]'});1290* }1291* }, function(err, results) {1292* console.log('err = ', err);1293* console.log('email_link = ', results.email_link);1294* });1295*1296* // If you are using a JS minifier that mangles parameter names, `autoInject`1297* // will not work with plain functions, since the parameter names will be1298* // collapsed to a single letter identifier. To work around this, you can1299* // explicitly specify the names of the parameters your task function needs1300* // in an array, similar to Angular.js dependency injection.1301*1302* // This still has an advantage over plain `auto`, since the results a task1303* // depends on are still spread into arguments.1304* async.autoInject({1305* //...1306* write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {1307* callback(null, 'filename');1308* }],1309* email_link: ['write_file', function(write_file, callback) {1310* callback(null, {'file':write_file, 'email':'[email protected]'});1311* }]1312* //...1313* }, function(err, results) {1314* console.log('err = ', err);1315* console.log('email_link = ', results.email_link);1316* });1317*/1318function autoInject(tasks, callback) {1319var newTasks = {};13201321Object.keys(tasks).forEach(key => {1322var taskFn = tasks[key];1323var params;1324var fnIsAsync = isAsync(taskFn);1325var hasNoDeps =1326(!fnIsAsync && taskFn.length === 1) ||1327(fnIsAsync && taskFn.length === 0);13281329if (Array.isArray(taskFn)) {1330params = [...taskFn];1331taskFn = params.pop();13321333newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);1334} else if (hasNoDeps) {1335// no dependencies, use the function as-is1336newTasks[key] = taskFn;1337} else {1338params = parseParams(taskFn);1339if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {1340throw new Error("autoInject task functions require explicit parameters.");1341}13421343// remove callback param1344if (!fnIsAsync) params.pop();13451346newTasks[key] = params.concat(newTask);1347}13481349function newTask(results, taskCb) {1350var newArgs = params.map(name => results[name]);1351newArgs.push(taskCb);1352wrapAsync(taskFn)(...newArgs);1353}1354});13551356return auto(newTasks, callback);1357}13581359// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation1360// used for queues. This implementation assumes that the node provided by the user can be modified1361// to adjust the next and last properties. We implement only the minimal functionality1362// for queue support.1363class DLL {1364constructor() {1365this.head = this.tail = null;1366this.length = 0;1367}13681369removeLink(node) {1370if (node.prev) node.prev.next = node.next;1371else this.head = node.next;1372if (node.next) node.next.prev = node.prev;1373else this.tail = node.prev;13741375node.prev = node.next = null;1376this.length -= 1;1377return node;1378}13791380empty () {1381while(this.head) this.shift();1382return this;1383}13841385insertAfter(node, newNode) {1386newNode.prev = node;1387newNode.next = node.next;1388if (node.next) node.next.prev = newNode;1389else this.tail = newNode;1390node.next = newNode;1391this.length += 1;1392}13931394insertBefore(node, newNode) {1395newNode.prev = node.prev;1396newNode.next = node;1397if (node.prev) node.prev.next = newNode;1398else this.head = newNode;1399node.prev = newNode;1400this.length += 1;1401}14021403unshift(node) {1404if (this.head) this.insertBefore(this.head, node);1405else setInitial(this, node);1406}14071408push(node) {1409if (this.tail) this.insertAfter(this.tail, node);1410else setInitial(this, node);1411}14121413shift() {1414return this.head && this.removeLink(this.head);1415}14161417pop() {1418return this.tail && this.removeLink(this.tail);1419}14201421toArray() {1422return [...this]1423}14241425*[Symbol.iterator] () {1426var cur = this.head;1427while (cur) {1428yield cur.data;1429cur = cur.next;1430}1431}14321433remove (testFn) {1434var curr = this.head;1435while(curr) {1436var {next} = curr;1437if (testFn(curr)) {1438this.removeLink(curr);1439}1440curr = next;1441}1442return this;1443}1444}14451446function setInitial(dll, node) {1447dll.length = 1;1448dll.head = dll.tail = node;1449}14501451function queue(worker, concurrency, payload) {1452if (concurrency == null) {1453concurrency = 1;1454}1455else if(concurrency === 0) {1456throw new RangeError('Concurrency must not be zero');1457}14581459var _worker = wrapAsync(worker);1460var numRunning = 0;1461var workersList = [];1462const events = {1463error: [],1464drain: [],1465saturated: [],1466unsaturated: [],1467empty: []1468};14691470function on (event, handler) {1471events[event].push(handler);1472}14731474function once (event, handler) {1475const handleAndRemove = (...args) => {1476off(event, handleAndRemove);1477handler(...args);1478};1479events[event].push(handleAndRemove);1480}14811482function off (event, handler) {1483if (!event) return Object.keys(events).forEach(ev => events[ev] = [])1484if (!handler) return events[event] = []1485events[event] = events[event].filter(ev => ev !== handler);1486}14871488function trigger (event, ...args) {1489events[event].forEach(handler => handler(...args));1490}14911492var processingScheduled = false;1493function _insert(data, insertAtFront, rejectOnError, callback) {1494if (callback != null && typeof callback !== 'function') {1495throw new Error('task callback must be a function');1496}1497q.started = true;14981499var res, rej;1500function promiseCallback (err, ...args) {1501// we don't care about the error, let the global error handler1502// deal with it1503if (err) return rejectOnError ? rej(err) : res()1504if (args.length <= 1) return res(args[0])1505res(args);1506}15071508var item = {1509data,1510callback: rejectOnError ?1511promiseCallback :1512(callback || promiseCallback)1513};15141515if (insertAtFront) {1516q._tasks.unshift(item);1517} else {1518q._tasks.push(item);1519}15201521if (!processingScheduled) {1522processingScheduled = true;1523setImmediate$1(() => {1524processingScheduled = false;1525q.process();1526});1527}15281529if (rejectOnError || !callback) {1530return new Promise((resolve, reject) => {1531res = resolve;1532rej = reject;1533})1534}1535}15361537function _createCB(tasks) {1538return function (err, ...args) {1539numRunning -= 1;15401541for (var i = 0, l = tasks.length; i < l; i++) {1542var task = tasks[i];15431544var index = workersList.indexOf(task);1545if (index === 0) {1546workersList.shift();1547} else if (index > 0) {1548workersList.splice(index, 1);1549}15501551task.callback(err, ...args);15521553if (err != null) {1554trigger('error', err, task.data);1555}1556}15571558if (numRunning <= (q.concurrency - q.buffer) ) {1559trigger('unsaturated');1560}15611562if (q.idle()) {1563trigger('drain');1564}1565q.process();1566};1567}15681569function _maybeDrain(data) {1570if (data.length === 0 && q.idle()) {1571// call drain immediately if there are no tasks1572setImmediate$1(() => trigger('drain'));1573return true1574}1575return false1576}15771578const eventMethod = (name) => (handler) => {1579if (!handler) {1580return new Promise((resolve, reject) => {1581once(name, (err, data) => {1582if (err) return reject(err)1583resolve(data);1584});1585})1586}1587off(name);1588on(name, handler);15891590};15911592var isProcessing = false;1593var q = {1594_tasks: new DLL(),1595*[Symbol.iterator] () {1596yield* q._tasks[Symbol.iterator]();1597},1598concurrency,1599payload,1600buffer: concurrency / 4,1601started: false,1602paused: false,1603push (data, callback) {1604if (Array.isArray(data)) {1605if (_maybeDrain(data)) return1606return data.map(datum => _insert(datum, false, false, callback))1607}1608return _insert(data, false, false, callback);1609},1610pushAsync (data, callback) {1611if (Array.isArray(data)) {1612if (_maybeDrain(data)) return1613return data.map(datum => _insert(datum, false, true, callback))1614}1615return _insert(data, false, true, callback);1616},1617kill () {1618off();1619q._tasks.empty();1620},1621unshift (data, callback) {1622if (Array.isArray(data)) {1623if (_maybeDrain(data)) return1624return data.map(datum => _insert(datum, true, false, callback))1625}1626return _insert(data, true, false, callback);1627},1628unshiftAsync (data, callback) {1629if (Array.isArray(data)) {1630if (_maybeDrain(data)) return1631return data.map(datum => _insert(datum, true, true, callback))1632}1633return _insert(data, true, true, callback);1634},1635remove (testFn) {1636q._tasks.remove(testFn);1637},1638process () {1639// Avoid trying to start too many processing operations. This can occur1640// when callbacks resolve synchronously (#1267).1641if (isProcessing) {1642return;1643}1644isProcessing = true;1645while(!q.paused && numRunning < q.concurrency && q._tasks.length){1646var tasks = [], data = [];1647var l = q._tasks.length;1648if (q.payload) l = Math.min(l, q.payload);1649for (var i = 0; i < l; i++) {1650var node = q._tasks.shift();1651tasks.push(node);1652workersList.push(node);1653data.push(node.data);1654}16551656numRunning += 1;16571658if (q._tasks.length === 0) {1659trigger('empty');1660}16611662if (numRunning === q.concurrency) {1663trigger('saturated');1664}16651666var cb = onlyOnce(_createCB(tasks));1667_worker(data, cb);1668}1669isProcessing = false;1670},1671length () {1672return q._tasks.length;1673},1674running () {1675return numRunning;1676},1677workersList () {1678return workersList;1679},1680idle() {1681return q._tasks.length + numRunning === 0;1682},1683pause () {1684q.paused = true;1685},1686resume () {1687if (q.paused === false) { return; }1688q.paused = false;1689setImmediate$1(q.process);1690}1691};1692// define these as fixed properties, so people get useful errors when updating1693Object.defineProperties(q, {1694saturated: {1695writable: false,1696value: eventMethod('saturated')1697},1698unsaturated: {1699writable: false,1700value: eventMethod('unsaturated')1701},1702empty: {1703writable: false,1704value: eventMethod('empty')1705},1706drain: {1707writable: false,1708value: eventMethod('drain')1709},1710error: {1711writable: false,1712value: eventMethod('error')1713},1714});1715return q;1716}17171718/**1719* Creates a `cargo` object with the specified payload. Tasks added to the1720* cargo will be processed altogether (up to the `payload` limit). If the1721* `worker` is in progress, the task is queued until it becomes available. Once1722* the `worker` has completed some tasks, each callback of those tasks is1723* called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)1724* for how `cargo` and `queue` work.1725*1726* While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers1727* at a time, cargo passes an array of tasks to a single worker, repeating1728* when the worker is finished.1729*1730* @name cargo1731* @static1732* @memberOf module:ControlFlow1733* @method1734* @see [async.queue]{@link module:ControlFlow.queue}1735* @category Control Flow1736* @param {AsyncFunction} worker - An asynchronous function for processing an array1737* of queued tasks. Invoked with `(tasks, callback)`.1738* @param {number} [payload=Infinity] - An optional `integer` for determining1739* how many tasks should be processed per round; if omitted, the default is1740* unlimited.1741* @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can1742* attached as certain properties to listen for specific events during the1743* lifecycle of the cargo and inner queue.1744* @example1745*1746* // create a cargo object with payload 21747* var cargo = async.cargo(function(tasks, callback) {1748* for (var i=0; i<tasks.length; i++) {1749* console.log('hello ' + tasks[i].name);1750* }1751* callback();1752* }, 2);1753*1754* // add some items1755* cargo.push({name: 'foo'}, function(err) {1756* console.log('finished processing foo');1757* });1758* cargo.push({name: 'bar'}, function(err) {1759* console.log('finished processing bar');1760* });1761* await cargo.push({name: 'baz'});1762* console.log('finished processing baz');1763*/1764function cargo(worker, payload) {1765return queue(worker, 1, payload);1766}17671768/**1769* Creates a `cargoQueue` object with the specified payload. Tasks added to the1770* cargoQueue will be processed together (up to the `payload` limit) in `concurrency` parallel workers.1771* If the all `workers` are in progress, the task is queued until one becomes available. Once1772* a `worker` has completed some tasks, each callback of those tasks is1773* called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)1774* for how `cargo` and `queue` work.1775*1776* While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers1777* at a time, and [`cargo`]{@link module:ControlFlow.cargo} passes an array of tasks to a single worker,1778* the cargoQueue passes an array of tasks to multiple parallel workers.1779*1780* @name cargoQueue1781* @static1782* @memberOf module:ControlFlow1783* @method1784* @see [async.queue]{@link module:ControlFlow.queue}1785* @see [async.cargo]{@link module:ControlFLow.cargo}1786* @category Control Flow1787* @param {AsyncFunction} worker - An asynchronous function for processing an array1788* of queued tasks. Invoked with `(tasks, callback)`.1789* @param {number} [concurrency=1] - An `integer` for determining how many1790* `worker` functions should be run in parallel. If omitted, the concurrency1791* defaults to `1`. If the concurrency is `0`, an error is thrown.1792* @param {number} [payload=Infinity] - An optional `integer` for determining1793* how many tasks should be processed per round; if omitted, the default is1794* unlimited.1795* @returns {module:ControlFlow.QueueObject} A cargoQueue object to manage the tasks. Callbacks can1796* attached as certain properties to listen for specific events during the1797* lifecycle of the cargoQueue and inner queue.1798* @example1799*1800* // create a cargoQueue object with payload 2 and concurrency 21801* var cargoQueue = async.cargoQueue(function(tasks, callback) {1802* for (var i=0; i<tasks.length; i++) {1803* console.log('hello ' + tasks[i].name);1804* }1805* callback();1806* }, 2, 2);1807*1808* // add some items1809* cargoQueue.push({name: 'foo'}, function(err) {1810* console.log('finished processing foo');1811* });1812* cargoQueue.push({name: 'bar'}, function(err) {1813* console.log('finished processing bar');1814* });1815* cargoQueue.push({name: 'baz'}, function(err) {1816* console.log('finished processing baz');1817* });1818* cargoQueue.push({name: 'boo'}, function(err) {1819* console.log('finished processing boo');1820* });1821*/1822function cargo$1(worker, concurrency, payload) {1823return queue(worker, concurrency, payload);1824}18251826/**1827* Reduces `coll` into a single value using an async `iteratee` to return each1828* successive step. `memo` is the initial state of the reduction. This function1829* only operates in series.1830*1831* For performance reasons, it may make sense to split a call to this function1832* into a parallel map, and then use the normal `Array.prototype.reduce` on the1833* results. This function is for situations where each step in the reduction1834* needs to be async; if you can get the data before reducing it, then it's1835* probably a good idea to do so.1836*1837* @name reduce1838* @static1839* @memberOf module:Collections1840* @method1841* @alias inject1842* @alias foldl1843* @category Collection1844* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.1845* @param {*} memo - The initial state of the reduction.1846* @param {AsyncFunction} iteratee - A function applied to each item in the1847* array to produce the next step in the reduction.1848* The `iteratee` should complete with the next state of the reduction.1849* If the iteratee completes with an error, the reduction is stopped and the1850* main `callback` is immediately called with the error.1851* Invoked with (memo, item, callback).1852* @param {Function} [callback] - A callback which is called after all the1853* `iteratee` functions have finished. Result is the reduced value. Invoked with1854* (err, result).1855* @returns {Promise} a promise, if no callback is passed1856* @example1857*1858* // file1.txt is a file that is 1000 bytes in size1859* // file2.txt is a file that is 2000 bytes in size1860* // file3.txt is a file that is 3000 bytes in size1861* // file4.txt does not exist1862*1863* const fileList = ['file1.txt','file2.txt','file3.txt'];1864* const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt'];1865*1866* // asynchronous function that computes the file size in bytes1867* // file size is added to the memoized value, then returned1868* function getFileSizeInBytes(memo, file, callback) {1869* fs.stat(file, function(err, stat) {1870* if (err) {1871* return callback(err);1872* }1873* callback(null, memo + stat.size);1874* });1875* }1876*1877* // Using callbacks1878* async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) {1879* if (err) {1880* console.log(err);1881* } else {1882* console.log(result);1883* // 60001884* // which is the sum of the file sizes of the three files1885* }1886* });1887*1888* // Error Handling1889* async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) {1890* if (err) {1891* console.log(err);1892* // [ Error: ENOENT: no such file or directory ]1893* } else {1894* console.log(result);1895* }1896* });1897*1898* // Using Promises1899* async.reduce(fileList, 0, getFileSizeInBytes)1900* .then( result => {1901* console.log(result);1902* // 60001903* // which is the sum of the file sizes of the three files1904* }).catch( err => {1905* console.log(err);1906* });1907*1908* // Error Handling1909* async.reduce(withMissingFileList, 0, getFileSizeInBytes)1910* .then( result => {1911* console.log(result);1912* }).catch( err => {1913* console.log(err);1914* // [ Error: ENOENT: no such file or directory ]1915* });1916*1917* // Using async/await1918* async () => {1919* try {1920* let result = await async.reduce(fileList, 0, getFileSizeInBytes);1921* console.log(result);1922* // 60001923* // which is the sum of the file sizes of the three files1924* }1925* catch (err) {1926* console.log(err);1927* }1928* }1929*1930* // Error Handling1931* async () => {1932* try {1933* let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);1934* console.log(result);1935* }1936* catch (err) {1937* console.log(err);1938* // [ Error: ENOENT: no such file or directory ]1939* }1940* }1941*1942*/1943function reduce(coll, memo, iteratee, callback) {1944callback = once(callback);1945var _iteratee = wrapAsync(iteratee);1946return eachOfSeries$1(coll, (x, i, iterCb) => {1947_iteratee(memo, x, (err, v) => {1948memo = v;1949iterCb(err);1950});1951}, err => callback(err, memo));1952}1953var reduce$1 = awaitify(reduce, 4);19541955/**1956* Version of the compose function that is more natural to read. Each function1957* consumes the return value of the previous function. It is the equivalent of1958* [compose]{@link module:ControlFlow.compose} with the arguments reversed.1959*1960* Each function is executed with the `this` binding of the composed function.1961*1962* @name seq1963* @static1964* @memberOf module:ControlFlow1965* @method1966* @see [async.compose]{@link module:ControlFlow.compose}1967* @category Control Flow1968* @param {...AsyncFunction} functions - the asynchronous functions to compose1969* @returns {Function} a function that composes the `functions` in order1970* @example1971*1972* // Requires lodash (or underscore), express3 and dresende's orm2.1973* // Part of an app, that fetches cats of the logged user.1974* // This example uses `seq` function to avoid overnesting and error1975* // handling clutter.1976* app.get('/cats', function(request, response) {1977* var User = request.models.User;1978* async.seq(1979* User.get.bind(User), // 'User.get' has signature (id, callback(err, data))1980* function(user, fn) {1981* user.getCats(fn); // 'getCats' has signature (callback(err, data))1982* }1983* )(req.session.user_id, function (err, cats) {1984* if (err) {1985* console.error(err);1986* response.json({ status: 'error', message: err.message });1987* } else {1988* response.json({ status: 'ok', message: 'Cats found', data: cats });1989* }1990* });1991* });1992*/1993function seq(...functions) {1994var _functions = functions.map(wrapAsync);1995return function (...args) {1996var that = this;19971998var cb = args[args.length - 1];1999if (typeof cb == 'function') {2000args.pop();2001} else {2002cb = promiseCallback();2003}20042005reduce$1(_functions, args, (newargs, fn, iterCb) => {2006fn.apply(that, newargs.concat((err, ...nextargs) => {2007iterCb(err, nextargs);2008}));2009},2010(err, results) => cb(err, ...results));20112012return cb[PROMISE_SYMBOL]2013};2014}20152016/**2017* Creates a function which is a composition of the passed asynchronous2018* functions. Each function consumes the return value of the function that2019* follows. Composing functions `f()`, `g()`, and `h()` would produce the result2020* of `f(g(h()))`, only this version uses callbacks to obtain the return values.2021*2022* If the last argument to the composed function is not a function, a promise2023* is returned when you call it.2024*2025* Each function is executed with the `this` binding of the composed function.2026*2027* @name compose2028* @static2029* @memberOf module:ControlFlow2030* @method2031* @category Control Flow2032* @param {...AsyncFunction} functions - the asynchronous functions to compose2033* @returns {Function} an asynchronous function that is the composed2034* asynchronous `functions`2035* @example2036*2037* function add1(n, callback) {2038* setTimeout(function () {2039* callback(null, n + 1);2040* }, 10);2041* }2042*2043* function mul3(n, callback) {2044* setTimeout(function () {2045* callback(null, n * 3);2046* }, 10);2047* }2048*2049* var add1mul3 = async.compose(mul3, add1);2050* add1mul3(4, function (err, result) {2051* // result now equals 152052* });2053*/2054function compose(...args) {2055return seq(...args.reverse());2056}20572058/**2059* The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.2060*2061* @name mapLimit2062* @static2063* @memberOf module:Collections2064* @method2065* @see [async.map]{@link module:Collections.map}2066* @category Collection2067* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2068* @param {number} limit - The maximum number of async operations at a time.2069* @param {AsyncFunction} iteratee - An async function to apply to each item in2070* `coll`.2071* The iteratee should complete with the transformed item.2072* Invoked with (item, callback).2073* @param {Function} [callback] - A callback which is called when all `iteratee`2074* functions have finished, or an error occurs. Results is an array of the2075* transformed items from the `coll`. Invoked with (err, results).2076* @returns {Promise} a promise, if no callback is passed2077*/2078function mapLimit (coll, limit, iteratee, callback) {2079return _asyncMap(eachOfLimit(limit), coll, iteratee, callback)2080}2081var mapLimit$1 = awaitify(mapLimit, 4);20822083/**2084* The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.2085*2086* @name concatLimit2087* @static2088* @memberOf module:Collections2089* @method2090* @see [async.concat]{@link module:Collections.concat}2091* @category Collection2092* @alias flatMapLimit2093* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2094* @param {number} limit - The maximum number of async operations at a time.2095* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,2096* which should use an array as its result. Invoked with (item, callback).2097* @param {Function} [callback] - A callback which is called after all the2098* `iteratee` functions have finished, or an error occurs. Results is an array2099* containing the concatenated results of the `iteratee` function. Invoked with2100* (err, results).2101* @returns A Promise, if no callback is passed2102*/2103function concatLimit(coll, limit, iteratee, callback) {2104var _iteratee = wrapAsync(iteratee);2105return mapLimit$1(coll, limit, (val, iterCb) => {2106_iteratee(val, (err, ...args) => {2107if (err) return iterCb(err);2108return iterCb(err, args);2109});2110}, (err, mapResults) => {2111var result = [];2112for (var i = 0; i < mapResults.length; i++) {2113if (mapResults[i]) {2114result = result.concat(...mapResults[i]);2115}2116}21172118return callback(err, result);2119});2120}2121var concatLimit$1 = awaitify(concatLimit, 4);21222123/**2124* Applies `iteratee` to each item in `coll`, concatenating the results. Returns2125* the concatenated list. The `iteratee`s are called in parallel, and the2126* results are concatenated as they return. The results array will be returned in2127* the original order of `coll` passed to the `iteratee` function.2128*2129* @name concat2130* @static2131* @memberOf module:Collections2132* @method2133* @category Collection2134* @alias flatMap2135* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2136* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,2137* which should use an array as its result. Invoked with (item, callback).2138* @param {Function} [callback] - A callback which is called after all the2139* `iteratee` functions have finished, or an error occurs. Results is an array2140* containing the concatenated results of the `iteratee` function. Invoked with2141* (err, results).2142* @returns A Promise, if no callback is passed2143* @example2144*2145* // dir1 is a directory that contains file1.txt, file2.txt2146* // dir2 is a directory that contains file3.txt, file4.txt2147* // dir3 is a directory that contains file5.txt2148* // dir4 does not exist2149*2150* let directoryList = ['dir1','dir2','dir3'];2151* let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];2152*2153* // Using callbacks2154* async.concat(directoryList, fs.readdir, function(err, results) {2155* if (err) {2156* console.log(err);2157* } else {2158* console.log(results);2159* // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]2160* }2161* });2162*2163* // Error Handling2164* async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {2165* if (err) {2166* console.log(err);2167* // [ Error: ENOENT: no such file or directory ]2168* // since dir4 does not exist2169* } else {2170* console.log(results);2171* }2172* });2173*2174* // Using Promises2175* async.concat(directoryList, fs.readdir)2176* .then(results => {2177* console.log(results);2178* // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]2179* }).catch(err => {2180* console.log(err);2181* });2182*2183* // Error Handling2184* async.concat(withMissingDirectoryList, fs.readdir)2185* .then(results => {2186* console.log(results);2187* }).catch(err => {2188* console.log(err);2189* // [ Error: ENOENT: no such file or directory ]2190* // since dir4 does not exist2191* });2192*2193* // Using async/await2194* async () => {2195* try {2196* let results = await async.concat(directoryList, fs.readdir);2197* console.log(results);2198* // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]2199* } catch (err) {2200* console.log(err);2201* }2202* }2203*2204* // Error Handling2205* async () => {2206* try {2207* let results = await async.concat(withMissingDirectoryList, fs.readdir);2208* console.log(results);2209* } catch (err) {2210* console.log(err);2211* // [ Error: ENOENT: no such file or directory ]2212* // since dir4 does not exist2213* }2214* }2215*2216*/2217function concat(coll, iteratee, callback) {2218return concatLimit$1(coll, Infinity, iteratee, callback)2219}2220var concat$1 = awaitify(concat, 3);22212222/**2223* The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.2224*2225* @name concatSeries2226* @static2227* @memberOf module:Collections2228* @method2229* @see [async.concat]{@link module:Collections.concat}2230* @category Collection2231* @alias flatMapSeries2232* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2233* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.2234* The iteratee should complete with an array an array of results.2235* Invoked with (item, callback).2236* @param {Function} [callback] - A callback which is called after all the2237* `iteratee` functions have finished, or an error occurs. Results is an array2238* containing the concatenated results of the `iteratee` function. Invoked with2239* (err, results).2240* @returns A Promise, if no callback is passed2241*/2242function concatSeries(coll, iteratee, callback) {2243return concatLimit$1(coll, 1, iteratee, callback)2244}2245var concatSeries$1 = awaitify(concatSeries, 3);22462247/**2248* Returns a function that when called, calls-back with the values provided.2249* Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to2250* [`auto`]{@link module:ControlFlow.auto}.2251*2252* @name constant2253* @static2254* @memberOf module:Utils2255* @method2256* @category Util2257* @param {...*} arguments... - Any number of arguments to automatically invoke2258* callback with.2259* @returns {AsyncFunction} Returns a function that when invoked, automatically2260* invokes the callback with the previous given arguments.2261* @example2262*2263* async.waterfall([2264* async.constant(42),2265* function (value, next) {2266* // value === 422267* },2268* //...2269* ], callback);2270*2271* async.waterfall([2272* async.constant(filename, "utf8"),2273* fs.readFile,2274* function (fileData, next) {2275* //...2276* }2277* //...2278* ], callback);2279*2280* async.auto({2281* hostname: async.constant("https://server.net/"),2282* port: findFreePort,2283* launchServer: ["hostname", "port", function (options, cb) {2284* startServer(options, cb);2285* }],2286* //...2287* }, callback);2288*/2289function constant(...args) {2290return function (...ignoredArgs/*, callback*/) {2291var callback = ignoredArgs.pop();2292return callback(null, ...args);2293};2294}22952296function _createTester(check, getResult) {2297return (eachfn, arr, _iteratee, cb) => {2298var testPassed = false;2299var testResult;2300const iteratee = wrapAsync(_iteratee);2301eachfn(arr, (value, _, callback) => {2302iteratee(value, (err, result) => {2303if (err || err === false) return callback(err);23042305if (check(result) && !testResult) {2306testPassed = true;2307testResult = getResult(true, value);2308return callback(null, breakLoop);2309}2310callback();2311});2312}, err => {2313if (err) return cb(err);2314cb(null, testPassed ? testResult : getResult(false));2315});2316};2317}23182319/**2320* Returns the first value in `coll` that passes an async truth test. The2321* `iteratee` is applied in parallel, meaning the first iteratee to return2322* `true` will fire the detect `callback` with that result. That means the2323* result might not be the first item in the original `coll` (in terms of order)2324* that passes the test.23252326* If order within the original `coll` is important, then look at2327* [`detectSeries`]{@link module:Collections.detectSeries}.2328*2329* @name detect2330* @static2331* @memberOf module:Collections2332* @method2333* @alias find2334* @category Collections2335* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2336* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.2337* The iteratee must complete with a boolean value as its result.2338* Invoked with (item, callback).2339* @param {Function} [callback] - A callback which is called as soon as any2340* iteratee returns `true`, or after all the `iteratee` functions have finished.2341* Result will be the first item in the array that passes the truth test2342* (iteratee) or the value `undefined` if none passed. Invoked with2343* (err, result).2344* @returns A Promise, if no callback is passed2345* @example2346*2347* // dir1 is a directory that contains file1.txt, file2.txt2348* // dir2 is a directory that contains file3.txt, file4.txt2349* // dir3 is a directory that contains file5.txt2350*2351* // asynchronous function that checks if a file exists2352* function fileExists(file, callback) {2353* fs.access(file, fs.constants.F_OK, (err) => {2354* callback(null, !err);2355* });2356* }2357*2358* async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,2359* function(err, result) {2360* console.log(result);2361* // dir1/file1.txt2362* // result now equals the first file in the list that exists2363* }2364*);2365*2366* // Using Promises2367* async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)2368* .then(result => {2369* console.log(result);2370* // dir1/file1.txt2371* // result now equals the first file in the list that exists2372* }).catch(err => {2373* console.log(err);2374* });2375*2376* // Using async/await2377* async () => {2378* try {2379* let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);2380* console.log(result);2381* // dir1/file1.txt2382* // result now equals the file in the list that exists2383* }2384* catch (err) {2385* console.log(err);2386* }2387* }2388*2389*/2390function detect(coll, iteratee, callback) {2391return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)2392}2393var detect$1 = awaitify(detect, 3);23942395/**2396* The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a2397* time.2398*2399* @name detectLimit2400* @static2401* @memberOf module:Collections2402* @method2403* @see [async.detect]{@link module:Collections.detect}2404* @alias findLimit2405* @category Collections2406* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2407* @param {number} limit - The maximum number of async operations at a time.2408* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.2409* The iteratee must complete with a boolean value as its result.2410* Invoked with (item, callback).2411* @param {Function} [callback] - A callback which is called as soon as any2412* iteratee returns `true`, or after all the `iteratee` functions have finished.2413* Result will be the first item in the array that passes the truth test2414* (iteratee) or the value `undefined` if none passed. Invoked with2415* (err, result).2416* @returns a Promise if no callback is passed2417*/2418function detectLimit(coll, limit, iteratee, callback) {2419return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback)2420}2421var detectLimit$1 = awaitify(detectLimit, 4);24222423/**2424* The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.2425*2426* @name detectSeries2427* @static2428* @memberOf module:Collections2429* @method2430* @see [async.detect]{@link module:Collections.detect}2431* @alias findSeries2432* @category Collections2433* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2434* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.2435* The iteratee must complete with a boolean value as its result.2436* Invoked with (item, callback).2437* @param {Function} [callback] - A callback which is called as soon as any2438* iteratee returns `true`, or after all the `iteratee` functions have finished.2439* Result will be the first item in the array that passes the truth test2440* (iteratee) or the value `undefined` if none passed. Invoked with2441* (err, result).2442* @returns a Promise if no callback is passed2443*/2444function detectSeries(coll, iteratee, callback) {2445return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback)2446}24472448var detectSeries$1 = awaitify(detectSeries, 3);24492450function consoleFunc(name) {2451return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {2452/* istanbul ignore else */2453if (typeof console === 'object') {2454/* istanbul ignore else */2455if (err) {2456/* istanbul ignore else */2457if (console.error) {2458console.error(err);2459}2460} else if (console[name]) { /* istanbul ignore else */2461resultArgs.forEach(x => console[name](x));2462}2463}2464})2465}24662467/**2468* Logs the result of an [`async` function]{@link AsyncFunction} to the2469* `console` using `console.dir` to display the properties of the resulting object.2470* Only works in Node.js or in browsers that support `console.dir` and2471* `console.error` (such as FF and Chrome).2472* If multiple arguments are returned from the async function,2473* `console.dir` is called on each argument in order.2474*2475* @name dir2476* @static2477* @memberOf module:Utils2478* @method2479* @category Util2480* @param {AsyncFunction} function - The function you want to eventually apply2481* all arguments to.2482* @param {...*} arguments... - Any number of arguments to apply to the function.2483* @example2484*2485* // in a module2486* var hello = function(name, callback) {2487* setTimeout(function() {2488* callback(null, {hello: name});2489* }, 1000);2490* };2491*2492* // in the node repl2493* node> async.dir(hello, 'world');2494* {hello: 'world'}2495*/2496var dir = consoleFunc('dir');24972498/**2499* The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in2500* the order of operations, the arguments `test` and `iteratee` are switched.2501*2502* `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.2503*2504* @name doWhilst2505* @static2506* @memberOf module:ControlFlow2507* @method2508* @see [async.whilst]{@link module:ControlFlow.whilst}2509* @category Control Flow2510* @param {AsyncFunction} iteratee - A function which is called each time `test`2511* passes. Invoked with (callback).2512* @param {AsyncFunction} test - asynchronous truth test to perform after each2513* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the2514* non-error args from the previous callback of `iteratee`.2515* @param {Function} [callback] - A callback which is called after the test2516* function has failed and repeated execution of `iteratee` has stopped.2517* `callback` will be passed an error and any arguments passed to the final2518* `iteratee`'s callback. Invoked with (err, [results]);2519* @returns {Promise} a promise, if no callback is passed2520*/2521function doWhilst(iteratee, test, callback) {2522callback = onlyOnce(callback);2523var _fn = wrapAsync(iteratee);2524var _test = wrapAsync(test);2525var results;25262527function next(err, ...args) {2528if (err) return callback(err);2529if (err === false) return;2530results = args;2531_test(...args, check);2532}25332534function check(err, truth) {2535if (err) return callback(err);2536if (err === false) return;2537if (!truth) return callback(null, ...results);2538_fn(next);2539}25402541return check(null, true);2542}25432544var doWhilst$1 = awaitify(doWhilst, 3);25452546/**2547* Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the2548* argument ordering differs from `until`.2549*2550* @name doUntil2551* @static2552* @memberOf module:ControlFlow2553* @method2554* @see [async.doWhilst]{@link module:ControlFlow.doWhilst}2555* @category Control Flow2556* @param {AsyncFunction} iteratee - An async function which is called each time2557* `test` fails. Invoked with (callback).2558* @param {AsyncFunction} test - asynchronous truth test to perform after each2559* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the2560* non-error args from the previous callback of `iteratee`2561* @param {Function} [callback] - A callback which is called after the test2562* function has passed and repeated execution of `iteratee` has stopped. `callback`2563* will be passed an error and any arguments passed to the final `iteratee`'s2564* callback. Invoked with (err, [results]);2565* @returns {Promise} a promise, if no callback is passed2566*/2567function doUntil(iteratee, test, callback) {2568const _test = wrapAsync(test);2569return doWhilst$1(iteratee, (...args) => {2570const cb = args.pop();2571_test(...args, (err, truth) => cb (err, !truth));2572}, callback);2573}25742575function _withoutIndex(iteratee) {2576return (value, index, callback) => iteratee(value, callback);2577}25782579/**2580* Applies the function `iteratee` to each item in `coll`, in parallel.2581* The `iteratee` is called with an item from the list, and a callback for when2582* it has finished. If the `iteratee` passes an error to its `callback`, the2583* main `callback` (for the `each` function) is immediately called with the2584* error.2585*2586* Note, that since this function applies `iteratee` to each item in parallel,2587* there is no guarantee that the iteratee functions will complete in order.2588*2589* @name each2590* @static2591* @memberOf module:Collections2592* @method2593* @alias forEach2594* @category Collection2595* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2596* @param {AsyncFunction} iteratee - An async function to apply to2597* each item in `coll`. Invoked with (item, callback).2598* The array index is not passed to the iteratee.2599* If you need the index, use `eachOf`.2600* @param {Function} [callback] - A callback which is called when all2601* `iteratee` functions have finished, or an error occurs. Invoked with (err).2602* @returns {Promise} a promise, if a callback is omitted2603* @example2604*2605* // dir1 is a directory that contains file1.txt, file2.txt2606* // dir2 is a directory that contains file3.txt, file4.txt2607* // dir3 is a directory that contains file5.txt2608* // dir4 does not exist2609*2610* const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];2611* const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];2612*2613* // asynchronous function that deletes a file2614* const deleteFile = function(file, callback) {2615* fs.unlink(file, callback);2616* };2617*2618* // Using callbacks2619* async.each(fileList, deleteFile, function(err) {2620* if( err ) {2621* console.log(err);2622* } else {2623* console.log('All files have been deleted successfully');2624* }2625* });2626*2627* // Error Handling2628* async.each(withMissingFileList, deleteFile, function(err){2629* console.log(err);2630* // [ Error: ENOENT: no such file or directory ]2631* // since dir4/file2.txt does not exist2632* // dir1/file1.txt could have been deleted2633* });2634*2635* // Using Promises2636* async.each(fileList, deleteFile)2637* .then( () => {2638* console.log('All files have been deleted successfully');2639* }).catch( err => {2640* console.log(err);2641* });2642*2643* // Error Handling2644* async.each(fileList, deleteFile)2645* .then( () => {2646* console.log('All files have been deleted successfully');2647* }).catch( err => {2648* console.log(err);2649* // [ Error: ENOENT: no such file or directory ]2650* // since dir4/file2.txt does not exist2651* // dir1/file1.txt could have been deleted2652* });2653*2654* // Using async/await2655* async () => {2656* try {2657* await async.each(files, deleteFile);2658* }2659* catch (err) {2660* console.log(err);2661* }2662* }2663*2664* // Error Handling2665* async () => {2666* try {2667* await async.each(withMissingFileList, deleteFile);2668* }2669* catch (err) {2670* console.log(err);2671* // [ Error: ENOENT: no such file or directory ]2672* // since dir4/file2.txt does not exist2673* // dir1/file1.txt could have been deleted2674* }2675* }2676*2677*/2678function eachLimit(coll, iteratee, callback) {2679return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);2680}26812682var each = awaitify(eachLimit, 3);26832684/**2685* The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.2686*2687* @name eachLimit2688* @static2689* @memberOf module:Collections2690* @method2691* @see [async.each]{@link module:Collections.each}2692* @alias forEachLimit2693* @category Collection2694* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2695* @param {number} limit - The maximum number of async operations at a time.2696* @param {AsyncFunction} iteratee - An async function to apply to each item in2697* `coll`.2698* The array index is not passed to the iteratee.2699* If you need the index, use `eachOfLimit`.2700* Invoked with (item, callback).2701* @param {Function} [callback] - A callback which is called when all2702* `iteratee` functions have finished, or an error occurs. Invoked with (err).2703* @returns {Promise} a promise, if a callback is omitted2704*/2705function eachLimit$1(coll, limit, iteratee, callback) {2706return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);2707}2708var eachLimit$2 = awaitify(eachLimit$1, 4);27092710/**2711* The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.2712*2713* Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item2714* in series and therefore the iteratee functions will complete in order.27152716* @name eachSeries2717* @static2718* @memberOf module:Collections2719* @method2720* @see [async.each]{@link module:Collections.each}2721* @alias forEachSeries2722* @category Collection2723* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2724* @param {AsyncFunction} iteratee - An async function to apply to each2725* item in `coll`.2726* The array index is not passed to the iteratee.2727* If you need the index, use `eachOfSeries`.2728* Invoked with (item, callback).2729* @param {Function} [callback] - A callback which is called when all2730* `iteratee` functions have finished, or an error occurs. Invoked with (err).2731* @returns {Promise} a promise, if a callback is omitted2732*/2733function eachSeries(coll, iteratee, callback) {2734return eachLimit$2(coll, 1, iteratee, callback)2735}2736var eachSeries$1 = awaitify(eachSeries, 3);27372738/**2739* Wrap an async function and ensure it calls its callback on a later tick of2740* the event loop. If the function already calls its callback on a next tick,2741* no extra deferral is added. This is useful for preventing stack overflows2742* (`RangeError: Maximum call stack size exceeded`) and generally keeping2743* [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)2744* contained. ES2017 `async` functions are returned as-is -- they are immune2745* to Zalgo's corrupting influences, as they always resolve on a later tick.2746*2747* @name ensureAsync2748* @static2749* @memberOf module:Utils2750* @method2751* @category Util2752* @param {AsyncFunction} fn - an async function, one that expects a node-style2753* callback as its last argument.2754* @returns {AsyncFunction} Returns a wrapped function with the exact same call2755* signature as the function passed in.2756* @example2757*2758* function sometimesAsync(arg, callback) {2759* if (cache[arg]) {2760* return callback(null, cache[arg]); // this would be synchronous!!2761* } else {2762* doSomeIO(arg, callback); // this IO would be asynchronous2763* }2764* }2765*2766* // this has a risk of stack overflows if many results are cached in a row2767* async.mapSeries(args, sometimesAsync, done);2768*2769* // this will defer sometimesAsync's callback if necessary,2770* // preventing stack overflows2771* async.mapSeries(args, async.ensureAsync(sometimesAsync), done);2772*/2773function ensureAsync(fn) {2774if (isAsync(fn)) return fn;2775return function (...args/*, callback*/) {2776var callback = args.pop();2777var sync = true;2778args.push((...innerArgs) => {2779if (sync) {2780setImmediate$1(() => callback(...innerArgs));2781} else {2782callback(...innerArgs);2783}2784});2785fn.apply(this, args);2786sync = false;2787};2788}27892790/**2791* Returns `true` if every element in `coll` satisfies an async test. If any2792* iteratee call returns `false`, the main `callback` is immediately called.2793*2794* @name every2795* @static2796* @memberOf module:Collections2797* @method2798* @alias all2799* @category Collection2800* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2801* @param {AsyncFunction} iteratee - An async truth test to apply to each item2802* in the collection in parallel.2803* The iteratee must complete with a boolean result value.2804* Invoked with (item, callback).2805* @param {Function} [callback] - A callback which is called after all the2806* `iteratee` functions have finished. Result will be either `true` or `false`2807* depending on the values of the async tests. Invoked with (err, result).2808* @returns {Promise} a promise, if no callback provided2809* @example2810*2811* // dir1 is a directory that contains file1.txt, file2.txt2812* // dir2 is a directory that contains file3.txt, file4.txt2813* // dir3 is a directory that contains file5.txt2814* // dir4 does not exist2815*2816* const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];2817* const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];2818*2819* // asynchronous function that checks if a file exists2820* function fileExists(file, callback) {2821* fs.access(file, fs.constants.F_OK, (err) => {2822* callback(null, !err);2823* });2824* }2825*2826* // Using callbacks2827* async.every(fileList, fileExists, function(err, result) {2828* console.log(result);2829* // true2830* // result is true since every file exists2831* });2832*2833* async.every(withMissingFileList, fileExists, function(err, result) {2834* console.log(result);2835* // false2836* // result is false since NOT every file exists2837* });2838*2839* // Using Promises2840* async.every(fileList, fileExists)2841* .then( result => {2842* console.log(result);2843* // true2844* // result is true since every file exists2845* }).catch( err => {2846* console.log(err);2847* });2848*2849* async.every(withMissingFileList, fileExists)2850* .then( result => {2851* console.log(result);2852* // false2853* // result is false since NOT every file exists2854* }).catch( err => {2855* console.log(err);2856* });2857*2858* // Using async/await2859* async () => {2860* try {2861* let result = await async.every(fileList, fileExists);2862* console.log(result);2863* // true2864* // result is true since every file exists2865* }2866* catch (err) {2867* console.log(err);2868* }2869* }2870*2871* async () => {2872* try {2873* let result = await async.every(withMissingFileList, fileExists);2874* console.log(result);2875* // false2876* // result is false since NOT every file exists2877* }2878* catch (err) {2879* console.log(err);2880* }2881* }2882*2883*/2884function every(coll, iteratee, callback) {2885return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)2886}2887var every$1 = awaitify(every, 3);28882889/**2890* The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.2891*2892* @name everyLimit2893* @static2894* @memberOf module:Collections2895* @method2896* @see [async.every]{@link module:Collections.every}2897* @alias allLimit2898* @category Collection2899* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2900* @param {number} limit - The maximum number of async operations at a time.2901* @param {AsyncFunction} iteratee - An async truth test to apply to each item2902* in the collection in parallel.2903* The iteratee must complete with a boolean result value.2904* Invoked with (item, callback).2905* @param {Function} [callback] - A callback which is called after all the2906* `iteratee` functions have finished. Result will be either `true` or `false`2907* depending on the values of the async tests. Invoked with (err, result).2908* @returns {Promise} a promise, if no callback provided2909*/2910function everyLimit(coll, limit, iteratee, callback) {2911return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback)2912}2913var everyLimit$1 = awaitify(everyLimit, 4);29142915/**2916* The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.2917*2918* @name everySeries2919* @static2920* @memberOf module:Collections2921* @method2922* @see [async.every]{@link module:Collections.every}2923* @alias allSeries2924* @category Collection2925* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2926* @param {AsyncFunction} iteratee - An async truth test to apply to each item2927* in the collection in series.2928* The iteratee must complete with a boolean result value.2929* Invoked with (item, callback).2930* @param {Function} [callback] - A callback which is called after all the2931* `iteratee` functions have finished. Result will be either `true` or `false`2932* depending on the values of the async tests. Invoked with (err, result).2933* @returns {Promise} a promise, if no callback provided2934*/2935function everySeries(coll, iteratee, callback) {2936return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)2937}2938var everySeries$1 = awaitify(everySeries, 3);29392940function filterArray(eachfn, arr, iteratee, callback) {2941var truthValues = new Array(arr.length);2942eachfn(arr, (x, index, iterCb) => {2943iteratee(x, (err, v) => {2944truthValues[index] = !!v;2945iterCb(err);2946});2947}, err => {2948if (err) return callback(err);2949var results = [];2950for (var i = 0; i < arr.length; i++) {2951if (truthValues[i]) results.push(arr[i]);2952}2953callback(null, results);2954});2955}29562957function filterGeneric(eachfn, coll, iteratee, callback) {2958var results = [];2959eachfn(coll, (x, index, iterCb) => {2960iteratee(x, (err, v) => {2961if (err) return iterCb(err);2962if (v) {2963results.push({index, value: x});2964}2965iterCb(err);2966});2967}, err => {2968if (err) return callback(err);2969callback(null, results2970.sort((a, b) => a.index - b.index)2971.map(v => v.value));2972});2973}29742975function _filter(eachfn, coll, iteratee, callback) {2976var filter = isArrayLike(coll) ? filterArray : filterGeneric;2977return filter(eachfn, coll, wrapAsync(iteratee), callback);2978}29792980/**2981* Returns a new array of all the values in `coll` which pass an async truth2982* test. This operation is performed in parallel, but the results array will be2983* in the same order as the original.2984*2985* @name filter2986* @static2987* @memberOf module:Collections2988* @method2989* @alias select2990* @category Collection2991* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2992* @param {Function} iteratee - A truth test to apply to each item in `coll`.2993* The `iteratee` is passed a `callback(err, truthValue)`, which must be called2994* with a boolean argument once it has completed. Invoked with (item, callback).2995* @param {Function} [callback] - A callback which is called after all the2996* `iteratee` functions have finished. Invoked with (err, results).2997* @returns {Promise} a promise, if no callback provided2998* @example2999*3000* // dir1 is a directory that contains file1.txt, file2.txt3001* // dir2 is a directory that contains file3.txt, file4.txt3002* // dir3 is a directory that contains file5.txt3003*3004* const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];3005*3006* // asynchronous function that checks if a file exists3007* function fileExists(file, callback) {3008* fs.access(file, fs.constants.F_OK, (err) => {3009* callback(null, !err);3010* });3011* }3012*3013* // Using callbacks3014* async.filter(files, fileExists, function(err, results) {3015* if(err) {3016* console.log(err);3017* } else {3018* console.log(results);3019* // [ 'dir1/file1.txt', 'dir2/file3.txt' ]3020* // results is now an array of the existing files3021* }3022* });3023*3024* // Using Promises3025* async.filter(files, fileExists)3026* .then(results => {3027* console.log(results);3028* // [ 'dir1/file1.txt', 'dir2/file3.txt' ]3029* // results is now an array of the existing files3030* }).catch(err => {3031* console.log(err);3032* });3033*3034* // Using async/await3035* async () => {3036* try {3037* let results = await async.filter(files, fileExists);3038* console.log(results);3039* // [ 'dir1/file1.txt', 'dir2/file3.txt' ]3040* // results is now an array of the existing files3041* }3042* catch (err) {3043* console.log(err);3044* }3045* }3046*3047*/3048function filter (coll, iteratee, callback) {3049return _filter(eachOf$1, coll, iteratee, callback)3050}3051var filter$1 = awaitify(filter, 3);30523053/**3054* The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a3055* time.3056*3057* @name filterLimit3058* @static3059* @memberOf module:Collections3060* @method3061* @see [async.filter]{@link module:Collections.filter}3062* @alias selectLimit3063* @category Collection3064* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3065* @param {number} limit - The maximum number of async operations at a time.3066* @param {Function} iteratee - A truth test to apply to each item in `coll`.3067* The `iteratee` is passed a `callback(err, truthValue)`, which must be called3068* with a boolean argument once it has completed. Invoked with (item, callback).3069* @param {Function} [callback] - A callback which is called after all the3070* `iteratee` functions have finished. Invoked with (err, results).3071* @returns {Promise} a promise, if no callback provided3072*/3073function filterLimit (coll, limit, iteratee, callback) {3074return _filter(eachOfLimit(limit), coll, iteratee, callback)3075}3076var filterLimit$1 = awaitify(filterLimit, 4);30773078/**3079* The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.3080*3081* @name filterSeries3082* @static3083* @memberOf module:Collections3084* @method3085* @see [async.filter]{@link module:Collections.filter}3086* @alias selectSeries3087* @category Collection3088* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3089* @param {Function} iteratee - A truth test to apply to each item in `coll`.3090* The `iteratee` is passed a `callback(err, truthValue)`, which must be called3091* with a boolean argument once it has completed. Invoked with (item, callback).3092* @param {Function} [callback] - A callback which is called after all the3093* `iteratee` functions have finished. Invoked with (err, results)3094* @returns {Promise} a promise, if no callback provided3095*/3096function filterSeries (coll, iteratee, callback) {3097return _filter(eachOfSeries$1, coll, iteratee, callback)3098}3099var filterSeries$1 = awaitify(filterSeries, 3);31003101/**3102* Calls the asynchronous function `fn` with a callback parameter that allows it3103* to call itself again, in series, indefinitely.31043105* If an error is passed to the callback then `errback` is called with the3106* error, and execution stops, otherwise it will never be called.3107*3108* @name forever3109* @static3110* @memberOf module:ControlFlow3111* @method3112* @category Control Flow3113* @param {AsyncFunction} fn - an async function to call repeatedly.3114* Invoked with (next).3115* @param {Function} [errback] - when `fn` passes an error to it's callback,3116* this function will be called, and execution stops. Invoked with (err).3117* @returns {Promise} a promise that rejects if an error occurs and an errback3118* is not passed3119* @example3120*3121* async.forever(3122* function(next) {3123* // next is suitable for passing to things that need a callback(err [, whatever]);3124* // it will result in this function being called again.3125* },3126* function(err) {3127* // if next is called with a value in its first parameter, it will appear3128* // in here as 'err', and execution will stop.3129* }3130* );3131*/3132function forever(fn, errback) {3133var done = onlyOnce(errback);3134var task = wrapAsync(ensureAsync(fn));31353136function next(err) {3137if (err) return done(err);3138if (err === false) return;3139task(next);3140}3141return next();3142}3143var forever$1 = awaitify(forever, 2);31443145/**3146* The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.3147*3148* @name groupByLimit3149* @static3150* @memberOf module:Collections3151* @method3152* @see [async.groupBy]{@link module:Collections.groupBy}3153* @category Collection3154* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3155* @param {number} limit - The maximum number of async operations at a time.3156* @param {AsyncFunction} iteratee - An async function to apply to each item in3157* `coll`.3158* The iteratee should complete with a `key` to group the value under.3159* Invoked with (value, callback).3160* @param {Function} [callback] - A callback which is called when all `iteratee`3161* functions have finished, or an error occurs. Result is an `Object` whoses3162* properties are arrays of values which returned the corresponding key.3163* @returns {Promise} a promise, if no callback is passed3164*/3165function groupByLimit(coll, limit, iteratee, callback) {3166var _iteratee = wrapAsync(iteratee);3167return mapLimit$1(coll, limit, (val, iterCb) => {3168_iteratee(val, (err, key) => {3169if (err) return iterCb(err);3170return iterCb(err, {key, val});3171});3172}, (err, mapResults) => {3173var result = {};3174// from MDN, handle object having an `hasOwnProperty` prop3175var {hasOwnProperty} = Object.prototype;31763177for (var i = 0; i < mapResults.length; i++) {3178if (mapResults[i]) {3179var {key} = mapResults[i];3180var {val} = mapResults[i];31813182if (hasOwnProperty.call(result, key)) {3183result[key].push(val);3184} else {3185result[key] = [val];3186}3187}3188}31893190return callback(err, result);3191});3192}31933194var groupByLimit$1 = awaitify(groupByLimit, 4);31953196/**3197* Returns a new object, where each value corresponds to an array of items, from3198* `coll`, that returned the corresponding key. That is, the keys of the object3199* correspond to the values passed to the `iteratee` callback.3200*3201* Note: Since this function applies the `iteratee` to each item in parallel,3202* there is no guarantee that the `iteratee` functions will complete in order.3203* However, the values for each key in the `result` will be in the same order as3204* the original `coll`. For Objects, the values will roughly be in the order of3205* the original Objects' keys (but this can vary across JavaScript engines).3206*3207* @name groupBy3208* @static3209* @memberOf module:Collections3210* @method3211* @category Collection3212* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3213* @param {AsyncFunction} iteratee - An async function to apply to each item in3214* `coll`.3215* The iteratee should complete with a `key` to group the value under.3216* Invoked with (value, callback).3217* @param {Function} [callback] - A callback which is called when all `iteratee`3218* functions have finished, or an error occurs. Result is an `Object` whoses3219* properties are arrays of values which returned the corresponding key.3220* @returns {Promise} a promise, if no callback is passed3221* @example3222*3223* // dir1 is a directory that contains file1.txt, file2.txt3224* // dir2 is a directory that contains file3.txt, file4.txt3225* // dir3 is a directory that contains file5.txt3226* // dir4 does not exist3227*3228* const files = ['dir1/file1.txt','dir2','dir4']3229*3230* // asynchronous function that detects file type as none, file, or directory3231* function detectFile(file, callback) {3232* fs.stat(file, function(err, stat) {3233* if (err) {3234* return callback(null, 'none');3235* }3236* callback(null, stat.isDirectory() ? 'directory' : 'file');3237* });3238* }3239*3240* //Using callbacks3241* async.groupBy(files, detectFile, function(err, result) {3242* if(err) {3243* console.log(err);3244* } else {3245* console.log(result);3246* // {3247* // file: [ 'dir1/file1.txt' ],3248* // none: [ 'dir4' ],3249* // directory: [ 'dir2']3250* // }3251* // result is object containing the files grouped by type3252* }3253* });3254*3255* // Using Promises3256* async.groupBy(files, detectFile)3257* .then( result => {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 type3265* }).catch( err => {3266* console.log(err);3267* });3268*3269* // Using async/await3270* async () => {3271* try {3272* let result = await async.groupBy(files, detectFile);3273* console.log(result);3274* // {3275* // file: [ 'dir1/file1.txt' ],3276* // none: [ 'dir4' ],3277* // directory: [ 'dir2']3278* // }3279* // result is object containing the files grouped by type3280* }3281* catch (err) {3282* console.log(err);3283* }3284* }3285*3286*/3287function groupBy (coll, iteratee, callback) {3288return groupByLimit$1(coll, Infinity, iteratee, callback)3289}32903291/**3292* The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.3293*3294* @name groupBySeries3295* @static3296* @memberOf module:Collections3297* @method3298* @see [async.groupBy]{@link module:Collections.groupBy}3299* @category Collection3300* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3301* @param {AsyncFunction} iteratee - An async function to apply to each item in3302* `coll`.3303* The iteratee should complete with a `key` to group the value under.3304* Invoked with (value, callback).3305* @param {Function} [callback] - A callback which is called when all `iteratee`3306* functions have finished, or an error occurs. Result is an `Object` whose3307* properties are arrays of values which returned the corresponding key.3308* @returns {Promise} a promise, if no callback is passed3309*/3310function groupBySeries (coll, iteratee, callback) {3311return groupByLimit$1(coll, 1, iteratee, callback)3312}33133314/**3315* Logs the result of an `async` function to the `console`. Only works in3316* Node.js or in browsers that support `console.log` and `console.error` (such3317* as FF and Chrome). If multiple arguments are returned from the async3318* function, `console.log` is called on each argument in order.3319*3320* @name log3321* @static3322* @memberOf module:Utils3323* @method3324* @category Util3325* @param {AsyncFunction} function - The function you want to eventually apply3326* all arguments to.3327* @param {...*} arguments... - Any number of arguments to apply to the function.3328* @example3329*3330* // in a module3331* var hello = function(name, callback) {3332* setTimeout(function() {3333* callback(null, 'hello ' + name);3334* }, 1000);3335* };3336*3337* // in the node repl3338* node> async.log(hello, 'world');3339* 'hello world'3340*/3341var log = consoleFunc('log');33423343/**3344* The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a3345* time.3346*3347* @name mapValuesLimit3348* @static3349* @memberOf module:Collections3350* @method3351* @see [async.mapValues]{@link module:Collections.mapValues}3352* @category Collection3353* @param {Object} obj - A collection to iterate over.3354* @param {number} limit - The maximum number of async operations at a time.3355* @param {AsyncFunction} iteratee - A function to apply to each value and key3356* in `coll`.3357* The iteratee should complete with the transformed value as its result.3358* Invoked with (value, key, callback).3359* @param {Function} [callback] - A callback which is called when all `iteratee`3360* functions have finished, or an error occurs. `result` is a new object consisting3361* of each key from `obj`, with each transformed value on the right-hand side.3362* Invoked with (err, result).3363* @returns {Promise} a promise, if no callback is passed3364*/3365function mapValuesLimit(obj, limit, iteratee, callback) {3366callback = once(callback);3367var newObj = {};3368var _iteratee = wrapAsync(iteratee);3369return eachOfLimit(limit)(obj, (val, key, next) => {3370_iteratee(val, key, (err, result) => {3371if (err) return next(err);3372newObj[key] = result;3373next(err);3374});3375}, err => callback(err, newObj));3376}33773378var mapValuesLimit$1 = awaitify(mapValuesLimit, 4);33793380/**3381* A relative of [`map`]{@link module:Collections.map}, designed for use with objects.3382*3383* Produces a new Object by mapping each value of `obj` through the `iteratee`3384* function. The `iteratee` is called each `value` and `key` from `obj` and a3385* callback for when it has finished processing. Each of these callbacks takes3386* two arguments: an `error`, and the transformed item from `obj`. If `iteratee`3387* passes an error to its callback, the main `callback` (for the `mapValues`3388* function) is immediately called with the error.3389*3390* Note, the order of the keys in the result is not guaranteed. The keys will3391* be roughly in the order they complete, (but this is very engine-specific)3392*3393* @name mapValues3394* @static3395* @memberOf module:Collections3396* @method3397* @category Collection3398* @param {Object} obj - A collection to iterate over.3399* @param {AsyncFunction} iteratee - A function to apply to each value and key3400* in `coll`.3401* The iteratee should complete with the transformed value as its result.3402* Invoked with (value, key, callback).3403* @param {Function} [callback] - A callback which is called when all `iteratee`3404* functions have finished, or an error occurs. `result` is a new object consisting3405* of each key from `obj`, with each transformed value on the right-hand side.3406* Invoked with (err, result).3407* @returns {Promise} a promise, if no callback is passed3408* @example3409*3410* // file1.txt is a file that is 1000 bytes in size3411* // file2.txt is a file that is 2000 bytes in size3412* // file3.txt is a file that is 3000 bytes in size3413* // file4.txt does not exist3414*3415* const fileMap = {3416* f1: 'file1.txt',3417* f2: 'file2.txt',3418* f3: 'file3.txt'3419* };3420*3421* const withMissingFileMap = {3422* f1: 'file1.txt',3423* f2: 'file2.txt',3424* f3: 'file4.txt'3425* };3426*3427* // asynchronous function that returns the file size in bytes3428* function getFileSizeInBytes(file, key, callback) {3429* fs.stat(file, function(err, stat) {3430* if (err) {3431* return callback(err);3432* }3433* callback(null, stat.size);3434* });3435* }3436*3437* // Using callbacks3438* async.mapValues(fileMap, getFileSizeInBytes, function(err, result) {3439* if (err) {3440* console.log(err);3441* } else {3442* console.log(result);3443* // result is now a map of file size in bytes for each file, e.g.3444* // {3445* // f1: 1000,3446* // f2: 2000,3447* // f3: 30003448* // }3449* }3450* });3451*3452* // Error handling3453* async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) {3454* if (err) {3455* console.log(err);3456* // [ Error: ENOENT: no such file or directory ]3457* } else {3458* console.log(result);3459* }3460* });3461*3462* // Using Promises3463* async.mapValues(fileMap, getFileSizeInBytes)3464* .then( result => {3465* console.log(result);3466* // result is now a map of file size in bytes for each file, e.g.3467* // {3468* // f1: 1000,3469* // f2: 2000,3470* // f3: 30003471* // }3472* }).catch (err => {3473* console.log(err);3474* });3475*3476* // Error Handling3477* async.mapValues(withMissingFileMap, getFileSizeInBytes)3478* .then( result => {3479* console.log(result);3480* }).catch (err => {3481* console.log(err);3482* // [ Error: ENOENT: no such file or directory ]3483* });3484*3485* // Using async/await3486* async () => {3487* try {3488* let result = await async.mapValues(fileMap, getFileSizeInBytes);3489* console.log(result);3490* // result is now a map of file size in bytes for each file, e.g.3491* // {3492* // f1: 1000,3493* // f2: 2000,3494* // f3: 30003495* // }3496* }3497* catch (err) {3498* console.log(err);3499* }3500* }3501*3502* // Error Handling3503* async () => {3504* try {3505* let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes);3506* console.log(result);3507* }3508* catch (err) {3509* console.log(err);3510* // [ Error: ENOENT: no such file or directory ]3511* }3512* }3513*3514*/3515function mapValues(obj, iteratee, callback) {3516return mapValuesLimit$1(obj, Infinity, iteratee, callback)3517}35183519/**3520* The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.3521*3522* @name mapValuesSeries3523* @static3524* @memberOf module:Collections3525* @method3526* @see [async.mapValues]{@link module:Collections.mapValues}3527* @category Collection3528* @param {Object} obj - A collection to iterate over.3529* @param {AsyncFunction} iteratee - A function to apply to each value and key3530* in `coll`.3531* The iteratee should complete with the transformed value as its result.3532* Invoked with (value, key, callback).3533* @param {Function} [callback] - A callback which is called when all `iteratee`3534* functions have finished, or an error occurs. `result` is a new object consisting3535* of each key from `obj`, with each transformed value on the right-hand side.3536* Invoked with (err, result).3537* @returns {Promise} a promise, if no callback is passed3538*/3539function mapValuesSeries(obj, iteratee, callback) {3540return mapValuesLimit$1(obj, 1, iteratee, callback)3541}35423543/**3544* Caches the results of an async function. When creating a hash to store3545* function results against, the callback is omitted from the hash and an3546* optional hash function can be used.3547*3548* **Note: if the async function errs, the result will not be cached and3549* subsequent calls will call the wrapped function.**3550*3551* If no hash function is specified, the first argument is used as a hash key,3552* which may work reasonably if it is a string or a data type that converts to a3553* distinct string. Note that objects and arrays will not behave reasonably.3554* Neither will cases where the other arguments are significant. In such cases,3555* specify your own hash function.3556*3557* The cache of results is exposed as the `memo` property of the function3558* returned by `memoize`.3559*3560* @name memoize3561* @static3562* @memberOf module:Utils3563* @method3564* @category Util3565* @param {AsyncFunction} fn - The async function to proxy and cache results from.3566* @param {Function} hasher - An optional function for generating a custom hash3567* for storing results. It has all the arguments applied to it apart from the3568* callback, and must be synchronous.3569* @returns {AsyncFunction} a memoized version of `fn`3570* @example3571*3572* var slow_fn = function(name, callback) {3573* // do something3574* callback(null, result);3575* };3576* var fn = async.memoize(slow_fn);3577*3578* // fn can now be used as if it were slow_fn3579* fn('some name', function() {3580* // callback3581* });3582*/3583function memoize(fn, hasher = v => v) {3584var memo = Object.create(null);3585var queues = Object.create(null);3586var _fn = wrapAsync(fn);3587var memoized = initialParams((args, callback) => {3588var key = hasher(...args);3589if (key in memo) {3590setImmediate$1(() => callback(null, ...memo[key]));3591} else if (key in queues) {3592queues[key].push(callback);3593} else {3594queues[key] = [callback];3595_fn(...args, (err, ...resultArgs) => {3596// #1465 don't memoize if an error occurred3597if (!err) {3598memo[key] = resultArgs;3599}3600var q = queues[key];3601delete queues[key];3602for (var i = 0, l = q.length; i < l; i++) {3603q[i](err, ...resultArgs);3604}3605});3606}3607});3608memoized.memo = memo;3609memoized.unmemoized = fn;3610return memoized;3611}36123613/* istanbul ignore file */36143615/**3616* Calls `callback` on a later loop around the event loop. In Node.js this just3617* calls `process.nextTick`. In the browser it will use `setImmediate` if3618* available, otherwise `setTimeout(callback, 0)`, which means other higher3619* priority events may precede the execution of `callback`.3620*3621* This is used internally for browser-compatibility purposes.3622*3623* @name nextTick3624* @static3625* @memberOf module:Utils3626* @method3627* @see [async.setImmediate]{@link module:Utils.setImmediate}3628* @category Util3629* @param {Function} callback - The function to call on a later loop around3630* the event loop. Invoked with (args...).3631* @param {...*} args... - any number of additional arguments to pass to the3632* callback on the next tick.3633* @example3634*3635* var call_order = [];3636* async.nextTick(function() {3637* call_order.push('two');3638* // call_order now equals ['one','two']3639* });3640* call_order.push('one');3641*3642* async.setImmediate(function (a, b, c) {3643* // a, b, and c equal 1, 2, and 33644* }, 1, 2, 3);3645*/3646var _defer$1;36473648if (hasNextTick) {3649_defer$1 = process.nextTick;3650} else if (hasSetImmediate) {3651_defer$1 = setImmediate;3652} else {3653_defer$1 = fallback;3654}36553656var nextTick = wrap(_defer$1);36573658var _parallel = awaitify((eachfn, tasks, callback) => {3659var results = isArrayLike(tasks) ? [] : {};36603661eachfn(tasks, (task, key, taskCb) => {3662wrapAsync(task)((err, ...result) => {3663if (result.length < 2) {3664[result] = result;3665}3666results[key] = result;3667taskCb(err);3668});3669}, err => callback(err, results));3670}, 3);36713672/**3673* Run the `tasks` collection of functions in parallel, without waiting until3674* the previous function has completed. If any of the functions pass an error to3675* its callback, the main `callback` is immediately called with the value of the3676* error. Once the `tasks` have completed, the results are passed to the final3677* `callback` as an array.3678*3679* **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about3680* parallel execution of code. If your tasks do not use any timers or perform3681* any I/O, they will actually be executed in series. Any synchronous setup3682* sections for each task will happen one after the other. JavaScript remains3683* single-threaded.3684*3685* **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the3686* execution of other tasks when a task fails.3687*3688* It is also possible to use an object instead of an array. Each property will3689* be run as a function and the results will be passed to the final `callback`3690* as an object instead of an array. This can be a more readable way of handling3691* results from {@link async.parallel}.3692*3693* @name parallel3694* @static3695* @memberOf module:ControlFlow3696* @method3697* @category Control Flow3698* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of3699* [async functions]{@link AsyncFunction} to run.3700* Each async function can complete with any number of optional `result` values.3701* @param {Function} [callback] - An optional callback to run once all the3702* functions have completed successfully. This function gets a results array3703* (or object) containing all the result arguments passed to the task callbacks.3704* Invoked with (err, results).3705* @returns {Promise} a promise, if a callback is not passed3706*3707* @example3708*3709* //Using Callbacks3710* async.parallel([3711* function(callback) {3712* setTimeout(function() {3713* callback(null, 'one');3714* }, 200);3715* },3716* function(callback) {3717* setTimeout(function() {3718* callback(null, 'two');3719* }, 100);3720* }3721* ], function(err, results) {3722* console.log(results);3723* // results is equal to ['one','two'] even though3724* // the second function had a shorter timeout.3725* });3726*3727* // an example using an object instead of an array3728* async.parallel({3729* one: function(callback) {3730* setTimeout(function() {3731* callback(null, 1);3732* }, 200);3733* },3734* two: function(callback) {3735* setTimeout(function() {3736* callback(null, 2);3737* }, 100);3738* }3739* }, function(err, results) {3740* console.log(results);3741* // results is equal to: { one: 1, two: 2 }3742* });3743*3744* //Using Promises3745* async.parallel([3746* function(callback) {3747* setTimeout(function() {3748* callback(null, 'one');3749* }, 200);3750* },3751* function(callback) {3752* setTimeout(function() {3753* callback(null, 'two');3754* }, 100);3755* }3756* ]).then(results => {3757* console.log(results);3758* // results is equal to ['one','two'] even though3759* // the second function had a shorter timeout.3760* }).catch(err => {3761* console.log(err);3762* });3763*3764* // an example using an object instead of an array3765* async.parallel({3766* one: function(callback) {3767* setTimeout(function() {3768* callback(null, 1);3769* }, 200);3770* },3771* two: function(callback) {3772* setTimeout(function() {3773* callback(null, 2);3774* }, 100);3775* }3776* }).then(results => {3777* console.log(results);3778* // results is equal to: { one: 1, two: 2 }3779* }).catch(err => {3780* console.log(err);3781* });3782*3783* //Using async/await3784* async () => {3785* try {3786* let results = await async.parallel([3787* function(callback) {3788* setTimeout(function() {3789* callback(null, 'one');3790* }, 200);3791* },3792* function(callback) {3793* setTimeout(function() {3794* callback(null, 'two');3795* }, 100);3796* }3797* ]);3798* console.log(results);3799* // results is equal to ['one','two'] even though3800* // the second function had a shorter timeout.3801* }3802* catch (err) {3803* console.log(err);3804* }3805* }3806*3807* // an example using an object instead of an array3808* async () => {3809* try {3810* let results = await async.parallel({3811* one: function(callback) {3812* setTimeout(function() {3813* callback(null, 1);3814* }, 200);3815* },3816* two: function(callback) {3817* setTimeout(function() {3818* callback(null, 2);3819* }, 100);3820* }3821* });3822* console.log(results);3823* // results is equal to: { one: 1, two: 2 }3824* }3825* catch (err) {3826* console.log(err);3827* }3828* }3829*3830*/3831function parallel(tasks, callback) {3832return _parallel(eachOf$1, tasks, callback);3833}38343835/**3836* The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a3837* time.3838*3839* @name parallelLimit3840* @static3841* @memberOf module:ControlFlow3842* @method3843* @see [async.parallel]{@link module:ControlFlow.parallel}3844* @category Control Flow3845* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of3846* [async functions]{@link AsyncFunction} to run.3847* Each async function can complete with any number of optional `result` values.3848* @param {number} limit - The maximum number of async operations at a time.3849* @param {Function} [callback] - An optional callback to run once all the3850* functions have completed successfully. This function gets a results array3851* (or object) containing all the result arguments passed to the task callbacks.3852* Invoked with (err, results).3853* @returns {Promise} a promise, if a callback is not passed3854*/3855function parallelLimit(tasks, limit, callback) {3856return _parallel(eachOfLimit(limit), tasks, callback);3857}38583859/**3860* A queue of tasks for the worker function to complete.3861* @typedef {Iterable} QueueObject3862* @memberOf module:ControlFlow3863* @property {Function} length - a function returning the number of items3864* waiting to be processed. Invoke with `queue.length()`.3865* @property {boolean} started - a boolean indicating whether or not any3866* items have been pushed and processed by the queue.3867* @property {Function} running - a function returning the number of items3868* currently being processed. Invoke with `queue.running()`.3869* @property {Function} workersList - a function returning the array of items3870* currently being processed. Invoke with `queue.workersList()`.3871* @property {Function} idle - a function returning false if there are items3872* waiting or being processed, or true if not. Invoke with `queue.idle()`.3873* @property {number} concurrency - an integer for determining how many `worker`3874* functions should be run in parallel. This property can be changed after a3875* `queue` is created to alter the concurrency on-the-fly.3876* @property {number} payload - an integer that specifies how many items are3877* passed to the worker function at a time. only applies if this is a3878* [cargo]{@link module:ControlFlow.cargo} object3879* @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`3880* once the `worker` has finished processing the task. Instead of a single task,3881* a `tasks` array can be submitted. The respective callback is used for every3882* task in the list. Invoke with `queue.push(task, [callback])`,3883* @property {AsyncFunction} unshift - add a new task to the front of the `queue`.3884* Invoke with `queue.unshift(task, [callback])`.3885* @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns3886* a promise that rejects if an error occurs.3887* @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns3888* a promise that rejects if an error occurs.3889* @property {Function} remove - remove items from the queue that match a test3890* function. The test function will be passed an object with a `data` property,3891* and a `priority` property, if this is a3892* [priorityQueue]{@link module:ControlFlow.priorityQueue} object.3893* Invoked with `queue.remove(testFn)`, where `testFn` is of the form3894* `function ({data, priority}) {}` and returns a Boolean.3895* @property {Function} saturated - a function that sets a callback that is3896* called when the number of running workers hits the `concurrency` limit, and3897* further tasks will be queued. If the callback is omitted, `q.saturated()`3898* returns a promise for the next occurrence.3899* @property {Function} unsaturated - a function that sets a callback that is3900* called when the number of running workers is less than the `concurrency` &3901* `buffer` limits, and further tasks will not be queued. If the callback is3902* omitted, `q.unsaturated()` returns a promise for the next occurrence.3903* @property {number} buffer - A minimum threshold buffer in order to say that3904* the `queue` is `unsaturated`.3905* @property {Function} empty - a function that sets a callback that is called3906* when the last item from the `queue` is given to a `worker`. If the callback3907* is omitted, `q.empty()` returns a promise for the next occurrence.3908* @property {Function} drain - a function that sets a callback that is called3909* when the last item from the `queue` has returned from the `worker`. If the3910* callback is omitted, `q.drain()` returns a promise for the next occurrence.3911* @property {Function} error - a function that sets a callback that is called3912* when a task errors. Has the signature `function(error, task)`. If the3913* callback is omitted, `error()` returns a promise that rejects on the next3914* error.3915* @property {boolean} paused - a boolean for determining whether the queue is3916* in a paused state.3917* @property {Function} pause - a function that pauses the processing of tasks3918* until `resume()` is called. Invoke with `queue.pause()`.3919* @property {Function} resume - a function that resumes the processing of3920* queued tasks when the queue is paused. Invoke with `queue.resume()`.3921* @property {Function} kill - a function that removes the `drain` callback and3922* empties remaining tasks from the queue forcing it to go idle. No more tasks3923* should be pushed to the queue after calling this function. Invoke with `queue.kill()`.3924*3925* @example3926* const q = async.queue(worker, 2)3927* q.push(item1)3928* q.push(item2)3929* q.push(item3)3930* // queues are iterable, spread into an array to inspect3931* const items = [...q] // [item1, item2, item3]3932* // or use for of3933* for (let item of q) {3934* console.log(item)3935* }3936*3937* q.drain(() => {3938* console.log('all done')3939* })3940* // or3941* await q.drain()3942*/39433944/**3945* Creates a `queue` object with the specified `concurrency`. Tasks added to the3946* `queue` are processed in parallel (up to the `concurrency` limit). If all3947* `worker`s are in progress, the task is queued until one becomes available.3948* Once a `worker` completes a `task`, that `task`'s callback is called.3949*3950* @name queue3951* @static3952* @memberOf module:ControlFlow3953* @method3954* @category Control Flow3955* @param {AsyncFunction} worker - An async function for processing a queued task.3956* If you want to handle errors from an individual task, pass a callback to3957* `q.push()`. Invoked with (task, callback).3958* @param {number} [concurrency=1] - An `integer` for determining how many3959* `worker` functions should be run in parallel. If omitted, the concurrency3960* defaults to `1`. If the concurrency is `0`, an error is thrown.3961* @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be3962* attached as certain properties to listen for specific events during the3963* lifecycle of the queue.3964* @example3965*3966* // create a queue object with concurrency 23967* var q = async.queue(function(task, callback) {3968* console.log('hello ' + task.name);3969* callback();3970* }, 2);3971*3972* // assign a callback3973* q.drain(function() {3974* console.log('all items have been processed');3975* });3976* // or await the end3977* await q.drain()3978*3979* // assign an error callback3980* q.error(function(err, task) {3981* console.error('task experienced an error');3982* });3983*3984* // add some items to the queue3985* q.push({name: 'foo'}, function(err) {3986* console.log('finished processing foo');3987* });3988* // callback is optional3989* q.push({name: 'bar'});3990*3991* // add some items to the queue (batch-wise)3992* q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {3993* console.log('finished processing item');3994* });3995*3996* // add some items to the front of the queue3997* q.unshift({name: 'bar'}, function (err) {3998* console.log('finished processing bar');3999* });4000*/4001function queue$1 (worker, concurrency) {4002var _worker = wrapAsync(worker);4003return queue((items, cb) => {4004_worker(items[0], cb);4005}, concurrency, 1);4006}40074008// Binary min-heap implementation used for priority queue.4009// Implementation is stable, i.e. push time is considered for equal priorities4010class Heap {4011constructor() {4012this.heap = [];4013this.pushCount = Number.MIN_SAFE_INTEGER;4014}40154016get length() {4017return this.heap.length;4018}40194020empty () {4021this.heap = [];4022return this;4023}40244025percUp(index) {4026let p;40274028while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {4029let t = this.heap[index];4030this.heap[index] = this.heap[p];4031this.heap[p] = t;40324033index = p;4034}4035}40364037percDown(index) {4038let l;40394040while ((l=leftChi(index)) < this.heap.length) {4041if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {4042l = l+1;4043}40444045if (smaller(this.heap[index], this.heap[l])) {4046break;4047}40484049let t = this.heap[index];4050this.heap[index] = this.heap[l];4051this.heap[l] = t;40524053index = l;4054}4055}40564057push(node) {4058node.pushCount = ++this.pushCount;4059this.heap.push(node);4060this.percUp(this.heap.length-1);4061}40624063unshift(node) {4064return this.heap.push(node);4065}40664067shift() {4068let [top] = this.heap;40694070this.heap[0] = this.heap[this.heap.length-1];4071this.heap.pop();4072this.percDown(0);40734074return top;4075}40764077toArray() {4078return [...this];4079}40804081*[Symbol.iterator] () {4082for (let i = 0; i < this.heap.length; i++) {4083yield this.heap[i].data;4084}4085}40864087remove (testFn) {4088let j = 0;4089for (let i = 0; i < this.heap.length; i++) {4090if (!testFn(this.heap[i])) {4091this.heap[j] = this.heap[i];4092j++;4093}4094}40954096this.heap.splice(j);40974098for (let i = parent(this.heap.length-1); i >= 0; i--) {4099this.percDown(i);4100}41014102return this;4103}4104}41054106function leftChi(i) {4107return (i<<1)+1;4108}41094110function parent(i) {4111return ((i+1)>>1)-1;4112}41134114function smaller(x, y) {4115if (x.priority !== y.priority) {4116return x.priority < y.priority;4117}4118else {4119return x.pushCount < y.pushCount;4120}4121}41224123/**4124* The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and4125* completed in ascending priority order.4126*4127* @name priorityQueue4128* @static4129* @memberOf module:ControlFlow4130* @method4131* @see [async.queue]{@link module:ControlFlow.queue}4132* @category Control Flow4133* @param {AsyncFunction} worker - An async function for processing a queued task.4134* If you want to handle errors from an individual task, pass a callback to4135* `q.push()`.4136* Invoked with (task, callback).4137* @param {number} concurrency - An `integer` for determining how many `worker`4138* functions should be run in parallel. If omitted, the concurrency defaults to4139* `1`. If the concurrency is `0`, an error is thrown.4140* @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two4141* differences between `queue` and `priorityQueue` objects:4142* * `push(task, priority, [callback])` - `priority` should be a number. If an4143* array of `tasks` is given, all tasks will be assigned the same priority.4144* * The `unshift` method was removed.4145*/4146function priorityQueue(worker, concurrency) {4147// Start with a normal queue4148var q = queue$1(worker, concurrency);4149var processingScheduled = false;41504151q._tasks = new Heap();41524153// Override push to accept second parameter representing priority4154q.push = function(data, priority = 0, callback = () => {}) {4155if (typeof callback !== 'function') {4156throw new Error('task callback must be a function');4157}4158q.started = true;4159if (!Array.isArray(data)) {4160data = [data];4161}4162if (data.length === 0 && q.idle()) {4163// call drain immediately if there are no tasks4164return setImmediate$1(() => q.drain());4165}41664167for (var i = 0, l = data.length; i < l; i++) {4168var item = {4169data: data[i],4170priority,4171callback4172};41734174q._tasks.push(item);4175}41764177if (!processingScheduled) {4178processingScheduled = true;4179setImmediate$1(() => {4180processingScheduled = false;4181q.process();4182});4183}4184};41854186// Remove unshift function4187delete q.unshift;41884189return q;4190}41914192/**4193* Runs the `tasks` array of functions in parallel, without waiting until the4194* previous function has completed. Once any of the `tasks` complete or pass an4195* error to its callback, the main `callback` is immediately called. It's4196* equivalent to `Promise.race()`.4197*4198* @name race4199* @static4200* @memberOf module:ControlFlow4201* @method4202* @category Control Flow4203* @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}4204* to run. Each function can complete with an optional `result` value.4205* @param {Function} callback - A callback to run once any of the functions have4206* completed. This function gets an error or result from the first function that4207* completed. Invoked with (err, result).4208* @returns undefined4209* @example4210*4211* async.race([4212* function(callback) {4213* setTimeout(function() {4214* callback(null, 'one');4215* }, 200);4216* },4217* function(callback) {4218* setTimeout(function() {4219* callback(null, 'two');4220* }, 100);4221* }4222* ],4223* // main callback4224* function(err, result) {4225* // the result will be equal to 'two' as it finishes earlier4226* });4227*/4228function race(tasks, callback) {4229callback = once(callback);4230if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));4231if (!tasks.length) return callback();4232for (var i = 0, l = tasks.length; i < l; i++) {4233wrapAsync(tasks[i])(callback);4234}4235}42364237var race$1 = awaitify(race, 2);42384239/**4240* Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.4241*4242* @name reduceRight4243* @static4244* @memberOf module:Collections4245* @method4246* @see [async.reduce]{@link module:Collections.reduce}4247* @alias foldr4248* @category Collection4249* @param {Array} array - A collection to iterate over.4250* @param {*} memo - The initial state of the reduction.4251* @param {AsyncFunction} iteratee - A function applied to each item in the4252* array to produce the next step in the reduction.4253* The `iteratee` should complete with the next state of the reduction.4254* If the iteratee completes with an error, the reduction is stopped and the4255* main `callback` is immediately called with the error.4256* Invoked with (memo, item, callback).4257* @param {Function} [callback] - A callback which is called after all the4258* `iteratee` functions have finished. Result is the reduced value. Invoked with4259* (err, result).4260* @returns {Promise} a promise, if no callback is passed4261*/4262function reduceRight (array, memo, iteratee, callback) {4263var reversed = [...array].reverse();4264return reduce$1(reversed, memo, iteratee, callback);4265}42664267/**4268* Wraps the async function in another function that always completes with a4269* result object, even when it errors.4270*4271* The result object has either the property `error` or `value`.4272*4273* @name reflect4274* @static4275* @memberOf module:Utils4276* @method4277* @category Util4278* @param {AsyncFunction} fn - The async function you want to wrap4279* @returns {Function} - A function that always passes null to it's callback as4280* the error. The second argument to the callback will be an `object` with4281* either an `error` or a `value` property.4282* @example4283*4284* async.parallel([4285* async.reflect(function(callback) {4286* // do some stuff ...4287* callback(null, 'one');4288* }),4289* async.reflect(function(callback) {4290* // do some more stuff but error ...4291* callback('bad stuff happened');4292* }),4293* async.reflect(function(callback) {4294* // do some more stuff ...4295* callback(null, 'two');4296* })4297* ],4298* // optional callback4299* function(err, results) {4300* // values4301* // results[0].value = 'one'4302* // results[1].error = 'bad stuff happened'4303* // results[2].value = 'two'4304* });4305*/4306function reflect(fn) {4307var _fn = wrapAsync(fn);4308return initialParams(function reflectOn(args, reflectCallback) {4309args.push((error, ...cbArgs) => {4310let retVal = {};4311if (error) {4312retVal.error = error;4313}4314if (cbArgs.length > 0){4315var value = cbArgs;4316if (cbArgs.length <= 1) {4317[value] = cbArgs;4318}4319retVal.value = value;4320}4321reflectCallback(null, retVal);4322});43234324return _fn.apply(this, args);4325});4326}43274328/**4329* A helper function that wraps an array or an object of functions with `reflect`.4330*4331* @name reflectAll4332* @static4333* @memberOf module:Utils4334* @method4335* @see [async.reflect]{@link module:Utils.reflect}4336* @category Util4337* @param {Array|Object|Iterable} tasks - The collection of4338* [async functions]{@link AsyncFunction} to wrap in `async.reflect`.4339* @returns {Array} Returns an array of async functions, each wrapped in4340* `async.reflect`4341* @example4342*4343* let tasks = [4344* function(callback) {4345* setTimeout(function() {4346* callback(null, 'one');4347* }, 200);4348* },4349* function(callback) {4350* // do some more stuff but error ...4351* callback(new Error('bad stuff happened'));4352* },4353* function(callback) {4354* setTimeout(function() {4355* callback(null, 'two');4356* }, 100);4357* }4358* ];4359*4360* async.parallel(async.reflectAll(tasks),4361* // optional callback4362* function(err, results) {4363* // values4364* // results[0].value = 'one'4365* // results[1].error = Error('bad stuff happened')4366* // results[2].value = 'two'4367* });4368*4369* // an example using an object instead of an array4370* let tasks = {4371* one: function(callback) {4372* setTimeout(function() {4373* callback(null, 'one');4374* }, 200);4375* },4376* two: function(callback) {4377* callback('two');4378* },4379* three: function(callback) {4380* setTimeout(function() {4381* callback(null, 'three');4382* }, 100);4383* }4384* };4385*4386* async.parallel(async.reflectAll(tasks),4387* // optional callback4388* function(err, results) {4389* // values4390* // results.one.value = 'one'4391* // results.two.error = 'two'4392* // results.three.value = 'three'4393* });4394*/4395function reflectAll(tasks) {4396var results;4397if (Array.isArray(tasks)) {4398results = tasks.map(reflect);4399} else {4400results = {};4401Object.keys(tasks).forEach(key => {4402results[key] = reflect.call(this, tasks[key]);4403});4404}4405return results;4406}44074408function reject(eachfn, arr, _iteratee, callback) {4409const iteratee = wrapAsync(_iteratee);4410return _filter(eachfn, arr, (value, cb) => {4411iteratee(value, (err, v) => {4412cb(err, !v);4413});4414}, callback);4415}44164417/**4418* The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.4419*4420* @name reject4421* @static4422* @memberOf module:Collections4423* @method4424* @see [async.filter]{@link module:Collections.filter}4425* @category Collection4426* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4427* @param {Function} iteratee - An async truth test to apply to each item in4428* `coll`.4429* The should complete with a boolean value as its `result`.4430* Invoked with (item, callback).4431* @param {Function} [callback] - A callback which is called after all the4432* `iteratee` functions have finished. Invoked with (err, results).4433* @returns {Promise} a promise, if no callback is passed4434* @example4435*4436* // dir1 is a directory that contains file1.txt, file2.txt4437* // dir2 is a directory that contains file3.txt, file4.txt4438* // dir3 is a directory that contains file5.txt4439*4440* const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];4441*4442* // asynchronous function that checks if a file exists4443* function fileExists(file, callback) {4444* fs.access(file, fs.constants.F_OK, (err) => {4445* callback(null, !err);4446* });4447* }4448*4449* // Using callbacks4450* async.reject(fileList, fileExists, function(err, results) {4451* // [ 'dir3/file6.txt' ]4452* // results now equals an array of the non-existing files4453* });4454*4455* // Using Promises4456* async.reject(fileList, fileExists)4457* .then( results => {4458* console.log(results);4459* // [ 'dir3/file6.txt' ]4460* // results now equals an array of the non-existing files4461* }).catch( err => {4462* console.log(err);4463* });4464*4465* // Using async/await4466* async () => {4467* try {4468* let results = await async.reject(fileList, fileExists);4469* console.log(results);4470* // [ 'dir3/file6.txt' ]4471* // results now equals an array of the non-existing files4472* }4473* catch (err) {4474* console.log(err);4475* }4476* }4477*4478*/4479function reject$1 (coll, iteratee, callback) {4480return reject(eachOf$1, coll, iteratee, callback)4481}4482var reject$2 = awaitify(reject$1, 3);44834484/**4485* The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a4486* time.4487*4488* @name rejectLimit4489* @static4490* @memberOf module:Collections4491* @method4492* @see [async.reject]{@link module:Collections.reject}4493* @category Collection4494* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4495* @param {number} limit - The maximum number of async operations at a time.4496* @param {Function} iteratee - An async truth test to apply to each item in4497* `coll`.4498* The should complete with a boolean value as its `result`.4499* Invoked with (item, callback).4500* @param {Function} [callback] - A callback which is called after all the4501* `iteratee` functions have finished. Invoked with (err, results).4502* @returns {Promise} a promise, if no callback is passed4503*/4504function rejectLimit (coll, limit, iteratee, callback) {4505return reject(eachOfLimit(limit), coll, iteratee, callback)4506}4507var rejectLimit$1 = awaitify(rejectLimit, 4);45084509/**4510* The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.4511*4512* @name rejectSeries4513* @static4514* @memberOf module:Collections4515* @method4516* @see [async.reject]{@link module:Collections.reject}4517* @category Collection4518* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4519* @param {Function} iteratee - An async truth test to apply to each item in4520* `coll`.4521* The should complete with a boolean value as its `result`.4522* Invoked with (item, callback).4523* @param {Function} [callback] - A callback which is called after all the4524* `iteratee` functions have finished. Invoked with (err, results).4525* @returns {Promise} a promise, if no callback is passed4526*/4527function rejectSeries (coll, iteratee, callback) {4528return reject(eachOfSeries$1, coll, iteratee, callback)4529}4530var rejectSeries$1 = awaitify(rejectSeries, 3);45314532function constant$1(value) {4533return function () {4534return value;4535}4536}45374538/**4539* Attempts to get a successful response from `task` no more than `times` times4540* before returning an error. If the task is successful, the `callback` will be4541* passed the result of the successful task. If all attempts fail, the callback4542* will be passed the error and result (if any) of the final attempt.4543*4544* @name retry4545* @static4546* @memberOf module:ControlFlow4547* @method4548* @category Control Flow4549* @see [async.retryable]{@link module:ControlFlow.retryable}4550* @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an4551* object with `times` and `interval` or a number.4552* * `times` - The number of attempts to make before giving up. The default4553* is `5`.4554* * `interval` - The time to wait between retries, in milliseconds. The4555* default is `0`. The interval may also be specified as a function of the4556* retry count (see example).4557* * `errorFilter` - An optional synchronous function that is invoked on4558* erroneous result. If it returns `true` the retry attempts will continue;4559* if the function returns `false` the retry flow is aborted with the current4560* attempt's error and result being returned to the final callback.4561* Invoked with (err).4562* * If `opts` is a number, the number specifies the number of times to retry,4563* with the default interval of `0`.4564* @param {AsyncFunction} task - An async function to retry.4565* Invoked with (callback).4566* @param {Function} [callback] - An optional callback which is called when the4567* task has succeeded, or after the final failed attempt. It receives the `err`4568* and `result` arguments of the last attempt at completing the `task`. Invoked4569* with (err, results).4570* @returns {Promise} a promise if no callback provided4571*4572* @example4573*4574* // The `retry` function can be used as a stand-alone control flow by passing4575* // a callback, as shown below:4576*4577* // try calling apiMethod 3 times4578* async.retry(3, apiMethod, function(err, result) {4579* // do something with the result4580* });4581*4582* // try calling apiMethod 3 times, waiting 200 ms between each retry4583* async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {4584* // do something with the result4585* });4586*4587* // try calling apiMethod 10 times with exponential backoff4588* // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)4589* async.retry({4590* times: 10,4591* interval: function(retryCount) {4592* return 50 * Math.pow(2, retryCount);4593* }4594* }, apiMethod, function(err, result) {4595* // do something with the result4596* });4597*4598* // try calling apiMethod the default 5 times no delay between each retry4599* async.retry(apiMethod, function(err, result) {4600* // do something with the result4601* });4602*4603* // try calling apiMethod only when error condition satisfies, all other4604* // errors will abort the retry control flow and return to final callback4605* async.retry({4606* errorFilter: function(err) {4607* return err.message === 'Temporary error'; // only retry on a specific error4608* }4609* }, apiMethod, function(err, result) {4610* // do something with the result4611* });4612*4613* // to retry individual methods that are not as reliable within other4614* // control flow functions, use the `retryable` wrapper:4615* async.auto({4616* users: api.getUsers.bind(api),4617* payments: async.retryable(3, api.getPayments.bind(api))4618* }, function(err, results) {4619* // do something with the results4620* });4621*4622*/4623const DEFAULT_TIMES = 5;4624const DEFAULT_INTERVAL = 0;46254626function retry(opts, task, callback) {4627var options = {4628times: DEFAULT_TIMES,4629intervalFunc: constant$1(DEFAULT_INTERVAL)4630};46314632if (arguments.length < 3 && typeof opts === 'function') {4633callback = task || promiseCallback();4634task = opts;4635} else {4636parseTimes(options, opts);4637callback = callback || promiseCallback();4638}46394640if (typeof task !== 'function') {4641throw new Error("Invalid arguments for async.retry");4642}46434644var _task = wrapAsync(task);46454646var attempt = 1;4647function retryAttempt() {4648_task((err, ...args) => {4649if (err === false) return4650if (err && attempt++ < options.times &&4651(typeof options.errorFilter != 'function' ||4652options.errorFilter(err))) {4653setTimeout(retryAttempt, options.intervalFunc(attempt - 1));4654} else {4655callback(err, ...args);4656}4657});4658}46594660retryAttempt();4661return callback[PROMISE_SYMBOL]4662}46634664function parseTimes(acc, t) {4665if (typeof t === 'object') {4666acc.times = +t.times || DEFAULT_TIMES;46674668acc.intervalFunc = typeof t.interval === 'function' ?4669t.interval :4670constant$1(+t.interval || DEFAULT_INTERVAL);46714672acc.errorFilter = t.errorFilter;4673} else if (typeof t === 'number' || typeof t === 'string') {4674acc.times = +t || DEFAULT_TIMES;4675} else {4676throw new Error("Invalid arguments for async.retry");4677}4678}46794680/**4681* A close relative of [`retry`]{@link module:ControlFlow.retry}. This method4682* wraps a task and makes it retryable, rather than immediately calling it4683* with retries.4684*4685* @name retryable4686* @static4687* @memberOf module:ControlFlow4688* @method4689* @see [async.retry]{@link module:ControlFlow.retry}4690* @category Control Flow4691* @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional4692* options, exactly the same as from `retry`, except for a `opts.arity` that4693* is the arity of the `task` function, defaulting to `task.length`4694* @param {AsyncFunction} task - the asynchronous function to wrap.4695* This function will be passed any arguments passed to the returned wrapper.4696* Invoked with (...args, callback).4697* @returns {AsyncFunction} The wrapped function, which when invoked, will4698* retry on an error, based on the parameters specified in `opts`.4699* This function will accept the same parameters as `task`.4700* @example4701*4702* async.auto({4703* dep1: async.retryable(3, getFromFlakyService),4704* process: ["dep1", async.retryable(3, function (results, cb) {4705* maybeProcessData(results.dep1, cb);4706* })]4707* }, callback);4708*/4709function retryable (opts, task) {4710if (!task) {4711task = opts;4712opts = null;4713}4714let arity = (opts && opts.arity) || task.length;4715if (isAsync(task)) {4716arity += 1;4717}4718var _task = wrapAsync(task);4719return initialParams((args, callback) => {4720if (args.length < arity - 1 || callback == null) {4721args.push(callback);4722callback = promiseCallback();4723}4724function taskFn(cb) {4725_task(...args, cb);4726}47274728if (opts) retry(opts, taskFn, callback);4729else retry(taskFn, callback);47304731return callback[PROMISE_SYMBOL]4732});4733}47344735/**4736* Run the functions in the `tasks` collection in series, each one running once4737* the previous function has completed. If any functions in the series pass an4738* error to its callback, no more functions are run, and `callback` is4739* immediately called with the value of the error. Otherwise, `callback`4740* receives an array of results when `tasks` have completed.4741*4742* It is also possible to use an object instead of an array. Each property will4743* be run as a function, and the results will be passed to the final `callback`4744* as an object instead of an array. This can be a more readable way of handling4745* results from {@link async.series}.4746*4747* **Note** that while many implementations preserve the order of object4748* properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)4749* explicitly states that4750*4751* > The mechanics and order of enumerating the properties is not specified.4752*4753* So if you rely on the order in which your series of functions are executed,4754* and want this to work on all platforms, consider using an array.4755*4756* @name series4757* @static4758* @memberOf module:ControlFlow4759* @method4760* @category Control Flow4761* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing4762* [async functions]{@link AsyncFunction} to run in series.4763* Each function can complete with any number of optional `result` values.4764* @param {Function} [callback] - An optional callback to run once all the4765* functions have completed. This function gets a results array (or object)4766* containing all the result arguments passed to the `task` callbacks. Invoked4767* with (err, result).4768* @return {Promise} a promise, if no callback is passed4769* @example4770*4771* //Using Callbacks4772* async.series([4773* function(callback) {4774* setTimeout(function() {4775* // do some async task4776* callback(null, 'one');4777* }, 200);4778* },4779* function(callback) {4780* setTimeout(function() {4781* // then do another async task4782* callback(null, 'two');4783* }, 100);4784* }4785* ], function(err, results) {4786* console.log(results);4787* // results is equal to ['one','two']4788* });4789*4790* // an example using objects instead of arrays4791* async.series({4792* one: function(callback) {4793* setTimeout(function() {4794* // do some async task4795* callback(null, 1);4796* }, 200);4797* },4798* two: function(callback) {4799* setTimeout(function() {4800* // then do another async task4801* callback(null, 2);4802* }, 100);4803* }4804* }, function(err, results) {4805* console.log(results);4806* // results is equal to: { one: 1, two: 2 }4807* });4808*4809* //Using Promises4810* async.series([4811* function(callback) {4812* setTimeout(function() {4813* callback(null, 'one');4814* }, 200);4815* },4816* function(callback) {4817* setTimeout(function() {4818* callback(null, 'two');4819* }, 100);4820* }4821* ]).then(results => {4822* console.log(results);4823* // results is equal to ['one','two']4824* }).catch(err => {4825* console.log(err);4826* });4827*4828* // an example using an object instead of an array4829* async.series({4830* one: function(callback) {4831* setTimeout(function() {4832* // do some async task4833* callback(null, 1);4834* }, 200);4835* },4836* two: function(callback) {4837* setTimeout(function() {4838* // then do another async task4839* callback(null, 2);4840* }, 100);4841* }4842* }).then(results => {4843* console.log(results);4844* // results is equal to: { one: 1, two: 2 }4845* }).catch(err => {4846* console.log(err);4847* });4848*4849* //Using async/await4850* async () => {4851* try {4852* let results = await async.series([4853* function(callback) {4854* setTimeout(function() {4855* // do some async task4856* callback(null, 'one');4857* }, 200);4858* },4859* function(callback) {4860* setTimeout(function() {4861* // then do another async task4862* callback(null, 'two');4863* }, 100);4864* }4865* ]);4866* console.log(results);4867* // results is equal to ['one','two']4868* }4869* catch (err) {4870* console.log(err);4871* }4872* }4873*4874* // an example using an object instead of an array4875* async () => {4876* try {4877* let results = await async.parallel({4878* one: function(callback) {4879* setTimeout(function() {4880* // do some async task4881* callback(null, 1);4882* }, 200);4883* },4884* two: function(callback) {4885* setTimeout(function() {4886* // then do another async task4887* callback(null, 2);4888* }, 100);4889* }4890* });4891* console.log(results);4892* // results is equal to: { one: 1, two: 2 }4893* }4894* catch (err) {4895* console.log(err);4896* }4897* }4898*4899*/4900function series(tasks, callback) {4901return _parallel(eachOfSeries$1, tasks, callback);4902}49034904/**4905* Returns `true` if at least one element in the `coll` satisfies an async test.4906* If any iteratee call returns `true`, the main `callback` is immediately4907* called.4908*4909* @name some4910* @static4911* @memberOf module:Collections4912* @method4913* @alias any4914* @category Collection4915* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4916* @param {AsyncFunction} iteratee - An async truth test to apply to each item4917* in the collections in parallel.4918* The iteratee should complete with a boolean `result` value.4919* Invoked with (item, callback).4920* @param {Function} [callback] - A callback which is called as soon as any4921* iteratee returns `true`, or after all the iteratee functions have finished.4922* Result will be either `true` or `false` depending on the values of the async4923* tests. Invoked with (err, result).4924* @returns {Promise} a promise, if no callback provided4925* @example4926*4927* // dir1 is a directory that contains file1.txt, file2.txt4928* // dir2 is a directory that contains file3.txt, file4.txt4929* // dir3 is a directory that contains file5.txt4930* // dir4 does not exist4931*4932* // asynchronous function that checks if a file exists4933* function fileExists(file, callback) {4934* fs.access(file, fs.constants.F_OK, (err) => {4935* callback(null, !err);4936* });4937* }4938*4939* // Using callbacks4940* async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,4941* function(err, result) {4942* console.log(result);4943* // true4944* // result is true since some file in the list exists4945* }4946*);4947*4948* async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,4949* function(err, result) {4950* console.log(result);4951* // false4952* // result is false since none of the files exists4953* }4954*);4955*4956* // Using Promises4957* async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)4958* .then( result => {4959* console.log(result);4960* // true4961* // result is true since some file in the list exists4962* }).catch( err => {4963* console.log(err);4964* });4965*4966* async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)4967* .then( result => {4968* console.log(result);4969* // false4970* // result is false since none of the files exists4971* }).catch( err => {4972* console.log(err);4973* });4974*4975* // Using async/await4976* async () => {4977* try {4978* let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);4979* console.log(result);4980* // true4981* // result is true since some file in the list exists4982* }4983* catch (err) {4984* console.log(err);4985* }4986* }4987*4988* async () => {4989* try {4990* let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);4991* console.log(result);4992* // false4993* // result is false since none of the files exists4994* }4995* catch (err) {4996* console.log(err);4997* }4998* }4999*5000*/5001function some(coll, iteratee, callback) {5002return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)5003}5004var some$1 = awaitify(some, 3);50055006/**5007* The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.5008*5009* @name someLimit5010* @static5011* @memberOf module:Collections5012* @method5013* @see [async.some]{@link module:Collections.some}5014* @alias anyLimit5015* @category Collection5016* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5017* @param {number} limit - The maximum number of async operations at a time.5018* @param {AsyncFunction} iteratee - An async truth test to apply to each item5019* in the collections in parallel.5020* The iteratee should complete with a boolean `result` value.5021* Invoked with (item, callback).5022* @param {Function} [callback] - A callback which is called as soon as any5023* iteratee returns `true`, or after all the iteratee functions have finished.5024* Result will be either `true` or `false` depending on the values of the async5025* tests. Invoked with (err, result).5026* @returns {Promise} a promise, if no callback provided5027*/5028function someLimit(coll, limit, iteratee, callback) {5029return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback)5030}5031var someLimit$1 = awaitify(someLimit, 4);50325033/**5034* The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.5035*5036* @name someSeries5037* @static5038* @memberOf module:Collections5039* @method5040* @see [async.some]{@link module:Collections.some}5041* @alias anySeries5042* @category Collection5043* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5044* @param {AsyncFunction} iteratee - An async truth test to apply to each item5045* in the collections in series.5046* The iteratee should complete with a boolean `result` value.5047* Invoked with (item, callback).5048* @param {Function} [callback] - A callback which is called as soon as any5049* iteratee returns `true`, or after all the iteratee functions have finished.5050* Result will be either `true` or `false` depending on the values of the async5051* tests. Invoked with (err, result).5052* @returns {Promise} a promise, if no callback provided5053*/5054function someSeries(coll, iteratee, callback) {5055return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)5056}5057var someSeries$1 = awaitify(someSeries, 3);50585059/**5060* Sorts a list by the results of running each `coll` value through an async5061* `iteratee`.5062*5063* @name sortBy5064* @static5065* @memberOf module:Collections5066* @method5067* @category Collection5068* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5069* @param {AsyncFunction} iteratee - An async function to apply to each item in5070* `coll`.5071* The iteratee should complete with a value to use as the sort criteria as5072* its `result`.5073* Invoked with (item, callback).5074* @param {Function} callback - A callback which is called after all the5075* `iteratee` functions have finished, or an error occurs. Results is the items5076* from the original `coll` sorted by the values returned by the `iteratee`5077* calls. Invoked with (err, results).5078* @returns {Promise} a promise, if no callback passed5079* @example5080*5081* // bigfile.txt is a file that is 251100 bytes in size5082* // mediumfile.txt is a file that is 11000 bytes in size5083* // smallfile.txt is a file that is 121 bytes in size5084*5085* // asynchronous function that returns the file size in bytes5086* function getFileSizeInBytes(file, callback) {5087* fs.stat(file, function(err, stat) {5088* if (err) {5089* return callback(err);5090* }5091* callback(null, stat.size);5092* });5093* }5094*5095* // Using callbacks5096* async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,5097* function(err, results) {5098* if (err) {5099* console.log(err);5100* } else {5101* console.log(results);5102* // results is now the original array of files sorted by5103* // file size (ascending by default), e.g.5104* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5105* }5106* }5107* );5108*5109* // By modifying the callback parameter the5110* // sorting order can be influenced:5111*5112* // ascending order5113* async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {5114* getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {5115* if (getFileSizeErr) return callback(getFileSizeErr);5116* callback(null, fileSize);5117* });5118* }, function(err, results) {5119* if (err) {5120* console.log(err);5121* } else {5122* console.log(results);5123* // results is now the original array of files sorted by5124* // file size (ascending by default), e.g.5125* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5126* }5127* }5128* );5129*5130* // descending order5131* async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {5132* getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {5133* if (getFileSizeErr) {5134* return callback(getFileSizeErr);5135* }5136* callback(null, fileSize * -1);5137* });5138* }, function(err, results) {5139* if (err) {5140* console.log(err);5141* } else {5142* console.log(results);5143* // results is now the original array of files sorted by5144* // file size (ascending by default), e.g.5145* // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']5146* }5147* }5148* );5149*5150* // Error handling5151* async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,5152* function(err, results) {5153* if (err) {5154* console.log(err);5155* // [ Error: ENOENT: no such file or directory ]5156* } else {5157* console.log(results);5158* }5159* }5160* );5161*5162* // Using Promises5163* async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)5164* .then( results => {5165* console.log(results);5166* // results is now the original array of files sorted by5167* // file size (ascending by default), e.g.5168* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5169* }).catch( err => {5170* console.log(err);5171* });5172*5173* // Error handling5174* async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)5175* .then( results => {5176* console.log(results);5177* }).catch( err => {5178* console.log(err);5179* // [ Error: ENOENT: no such file or directory ]5180* });5181*5182* // Using async/await5183* (async () => {5184* try {5185* let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);5186* console.log(results);5187* // results is now the original array of files sorted by5188* // file size (ascending by default), e.g.5189* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5190* }5191* catch (err) {5192* console.log(err);5193* }5194* })();5195*5196* // Error handling5197* async () => {5198* try {5199* let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);5200* console.log(results);5201* }5202* catch (err) {5203* console.log(err);5204* // [ Error: ENOENT: no such file or directory ]5205* }5206* }5207*5208*/5209function sortBy (coll, iteratee, callback) {5210var _iteratee = wrapAsync(iteratee);5211return map$1(coll, (x, iterCb) => {5212_iteratee(x, (err, criteria) => {5213if (err) return iterCb(err);5214iterCb(err, {value: x, criteria});5215});5216}, (err, results) => {5217if (err) return callback(err);5218callback(null, results.sort(comparator).map(v => v.value));5219});52205221function comparator(left, right) {5222var a = left.criteria, b = right.criteria;5223return a < b ? -1 : a > b ? 1 : 0;5224}5225}5226var sortBy$1 = awaitify(sortBy, 3);52275228/**5229* Sets a time limit on an asynchronous function. If the function does not call5230* its callback within the specified milliseconds, it will be called with a5231* timeout error. The code property for the error object will be `'ETIMEDOUT'`.5232*5233* @name timeout5234* @static5235* @memberOf module:Utils5236* @method5237* @category Util5238* @param {AsyncFunction} asyncFn - The async function to limit in time.5239* @param {number} milliseconds - The specified time limit.5240* @param {*} [info] - Any variable you want attached (`string`, `object`, etc)5241* to timeout Error for more information..5242* @returns {AsyncFunction} Returns a wrapped function that can be used with any5243* of the control flow functions.5244* Invoke this function with the same parameters as you would `asyncFunc`.5245* @example5246*5247* function myFunction(foo, callback) {5248* doAsyncTask(foo, function(err, data) {5249* // handle errors5250* if (err) return callback(err);5251*5252* // do some stuff ...5253*5254* // return processed data5255* return callback(null, data);5256* });5257* }5258*5259* var wrapped = async.timeout(myFunction, 1000);5260*5261* // call `wrapped` as you would `myFunction`5262* wrapped({ bar: 'bar' }, function(err, data) {5263* // if `myFunction` takes < 1000 ms to execute, `err`5264* // and `data` will have their expected values5265*5266* // else `err` will be an Error with the code 'ETIMEDOUT'5267* });5268*/5269function timeout(asyncFn, milliseconds, info) {5270var fn = wrapAsync(asyncFn);52715272return initialParams((args, callback) => {5273var timedOut = false;5274var timer;52755276function timeoutCallback() {5277var name = asyncFn.name || 'anonymous';5278var error = new Error('Callback function "' + name + '" timed out.');5279error.code = 'ETIMEDOUT';5280if (info) {5281error.info = info;5282}5283timedOut = true;5284callback(error);5285}52865287args.push((...cbArgs) => {5288if (!timedOut) {5289callback(...cbArgs);5290clearTimeout(timer);5291}5292});52935294// setup timer and call original function5295timer = setTimeout(timeoutCallback, milliseconds);5296fn(...args);5297});5298}52995300function range(size) {5301var result = Array(size);5302while (size--) {5303result[size] = size;5304}5305return result;5306}53075308/**5309* The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a5310* time.5311*5312* @name timesLimit5313* @static5314* @memberOf module:ControlFlow5315* @method5316* @see [async.times]{@link module:ControlFlow.times}5317* @category Control Flow5318* @param {number} count - The number of times to run the function.5319* @param {number} limit - The maximum number of async operations at a time.5320* @param {AsyncFunction} iteratee - The async function to call `n` times.5321* Invoked with the iteration index and a callback: (n, next).5322* @param {Function} callback - see [async.map]{@link module:Collections.map}.5323* @returns {Promise} a promise, if no callback is provided5324*/5325function timesLimit(count, limit, iteratee, callback) {5326var _iteratee = wrapAsync(iteratee);5327return mapLimit$1(range(count), limit, _iteratee, callback);5328}53295330/**5331* Calls the `iteratee` function `n` times, and accumulates results in the same5332* manner you would use with [map]{@link module:Collections.map}.5333*5334* @name times5335* @static5336* @memberOf module:ControlFlow5337* @method5338* @see [async.map]{@link module:Collections.map}5339* @category Control Flow5340* @param {number} n - The number of times to run the function.5341* @param {AsyncFunction} iteratee - The async function to call `n` times.5342* Invoked with the iteration index and a callback: (n, next).5343* @param {Function} callback - see {@link module:Collections.map}.5344* @returns {Promise} a promise, if no callback is provided5345* @example5346*5347* // Pretend this is some complicated async factory5348* var createUser = function(id, callback) {5349* callback(null, {5350* id: 'user' + id5351* });5352* };5353*5354* // generate 5 users5355* async.times(5, function(n, next) {5356* createUser(n, function(err, user) {5357* next(err, user);5358* });5359* }, function(err, users) {5360* // we should now have 5 users5361* });5362*/5363function times (n, iteratee, callback) {5364return timesLimit(n, Infinity, iteratee, callback)5365}53665367/**5368* The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.5369*5370* @name timesSeries5371* @static5372* @memberOf module:ControlFlow5373* @method5374* @see [async.times]{@link module:ControlFlow.times}5375* @category Control Flow5376* @param {number} n - The number of times to run the function.5377* @param {AsyncFunction} iteratee - The async function to call `n` times.5378* Invoked with the iteration index and a callback: (n, next).5379* @param {Function} callback - see {@link module:Collections.map}.5380* @returns {Promise} a promise, if no callback is provided5381*/5382function timesSeries (n, iteratee, callback) {5383return timesLimit(n, 1, iteratee, callback)5384}53855386/**5387* A relative of `reduce`. Takes an Object or Array, and iterates over each5388* element in parallel, each step potentially mutating an `accumulator` value.5389* The type of the accumulator defaults to the type of collection passed in.5390*5391* @name transform5392* @static5393* @memberOf module:Collections5394* @method5395* @category Collection5396* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5397* @param {*} [accumulator] - The initial state of the transform. If omitted,5398* it will default to an empty Object or Array, depending on the type of `coll`5399* @param {AsyncFunction} iteratee - A function applied to each item in the5400* collection that potentially modifies the accumulator.5401* Invoked with (accumulator, item, key, callback).5402* @param {Function} [callback] - A callback which is called after all the5403* `iteratee` functions have finished. Result is the transformed accumulator.5404* Invoked with (err, result).5405* @returns {Promise} a promise, if no callback provided5406* @example5407*5408* // file1.txt is a file that is 1000 bytes in size5409* // file2.txt is a file that is 2000 bytes in size5410* // file3.txt is a file that is 3000 bytes in size5411*5412* // helper function that returns human-readable size format from bytes5413* function formatBytes(bytes, decimals = 2) {5414* // implementation not included for brevity5415* return humanReadbleFilesize;5416* }5417*5418* const fileList = ['file1.txt','file2.txt','file3.txt'];5419*5420* // asynchronous function that returns the file size, transformed to human-readable format5421* // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.5422* function transformFileSize(acc, value, key, callback) {5423* fs.stat(value, function(err, stat) {5424* if (err) {5425* return callback(err);5426* }5427* acc[key] = formatBytes(stat.size);5428* callback(null);5429* });5430* }5431*5432* // Using callbacks5433* async.transform(fileList, transformFileSize, function(err, result) {5434* if(err) {5435* console.log(err);5436* } else {5437* console.log(result);5438* // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]5439* }5440* });5441*5442* // Using Promises5443* async.transform(fileList, transformFileSize)5444* .then(result => {5445* console.log(result);5446* // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]5447* }).catch(err => {5448* console.log(err);5449* });5450*5451* // Using async/await5452* (async () => {5453* try {5454* let result = await async.transform(fileList, transformFileSize);5455* console.log(result);5456* // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]5457* }5458* catch (err) {5459* console.log(err);5460* }5461* })();5462*5463* @example5464*5465* // file1.txt is a file that is 1000 bytes in size5466* // file2.txt is a file that is 2000 bytes in size5467* // file3.txt is a file that is 3000 bytes in size5468*5469* // helper function that returns human-readable size format from bytes5470* function formatBytes(bytes, decimals = 2) {5471* // implementation not included for brevity5472* return humanReadbleFilesize;5473* }5474*5475* const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' };5476*5477* // asynchronous function that returns the file size, transformed to human-readable format5478* // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.5479* function transformFileSize(acc, value, key, callback) {5480* fs.stat(value, function(err, stat) {5481* if (err) {5482* return callback(err);5483* }5484* acc[key] = formatBytes(stat.size);5485* callback(null);5486* });5487* }5488*5489* // Using callbacks5490* async.transform(fileMap, transformFileSize, function(err, result) {5491* if(err) {5492* console.log(err);5493* } else {5494* console.log(result);5495* // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }5496* }5497* });5498*5499* // Using Promises5500* async.transform(fileMap, transformFileSize)5501* .then(result => {5502* console.log(result);5503* // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }5504* }).catch(err => {5505* console.log(err);5506* });5507*5508* // Using async/await5509* async () => {5510* try {5511* let result = await async.transform(fileMap, transformFileSize);5512* console.log(result);5513* // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }5514* }5515* catch (err) {5516* console.log(err);5517* }5518* }5519*5520*/5521function transform (coll, accumulator, iteratee, callback) {5522if (arguments.length <= 3 && typeof accumulator === 'function') {5523callback = iteratee;5524iteratee = accumulator;5525accumulator = Array.isArray(coll) ? [] : {};5526}5527callback = once(callback || promiseCallback());5528var _iteratee = wrapAsync(iteratee);55295530eachOf$1(coll, (v, k, cb) => {5531_iteratee(accumulator, v, k, cb);5532}, err => callback(err, accumulator));5533return callback[PROMISE_SYMBOL]5534}55355536/**5537* It runs each task in series but stops whenever any of the functions were5538* successful. If one of the tasks were successful, the `callback` will be5539* passed the result of the successful task. If all tasks fail, the callback5540* will be passed the error and result (if any) of the final attempt.5541*5542* @name tryEach5543* @static5544* @memberOf module:ControlFlow5545* @method5546* @category Control Flow5547* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to5548* run, each function is passed a `callback(err, result)` it must call on5549* completion with an error `err` (which can be `null`) and an optional `result`5550* value.5551* @param {Function} [callback] - An optional callback which is called when one5552* of the tasks has succeeded, or all have failed. It receives the `err` and5553* `result` arguments of the last attempt at completing the `task`. Invoked with5554* (err, results).5555* @returns {Promise} a promise, if no callback is passed5556* @example5557* async.tryEach([5558* function getDataFromFirstWebsite(callback) {5559* // Try getting the data from the first website5560* callback(err, data);5561* },5562* function getDataFromSecondWebsite(callback) {5563* // First website failed,5564* // Try getting the data from the backup website5565* callback(err, data);5566* }5567* ],5568* // optional callback5569* function(err, results) {5570* Now do something with the data.5571* });5572*5573*/5574function tryEach(tasks, callback) {5575var error = null;5576var result;5577return eachSeries$1(tasks, (task, taskCb) => {5578wrapAsync(task)((err, ...args) => {5579if (err === false) return taskCb(err);55805581if (args.length < 2) {5582[result] = args;5583} else {5584result = args;5585}5586error = err;5587taskCb(err ? null : {});5588});5589}, () => callback(error, result));5590}55915592var tryEach$1 = awaitify(tryEach);55935594/**5595* Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,5596* unmemoized form. Handy for testing.5597*5598* @name unmemoize5599* @static5600* @memberOf module:Utils5601* @method5602* @see [async.memoize]{@link module:Utils.memoize}5603* @category Util5604* @param {AsyncFunction} fn - the memoized function5605* @returns {AsyncFunction} a function that calls the original unmemoized function5606*/5607function unmemoize(fn) {5608return (...args) => {5609return (fn.unmemoized || fn)(...args);5610};5611}56125613/**5614* Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when5615* stopped, or an error occurs.5616*5617* @name whilst5618* @static5619* @memberOf module:ControlFlow5620* @method5621* @category Control Flow5622* @param {AsyncFunction} test - asynchronous truth test to perform before each5623* execution of `iteratee`. Invoked with ().5624* @param {AsyncFunction} iteratee - An async function which is called each time5625* `test` passes. Invoked with (callback).5626* @param {Function} [callback] - A callback which is called after the test5627* function has failed and repeated execution of `iteratee` has stopped. `callback`5628* will be passed an error and any arguments passed to the final `iteratee`'s5629* callback. Invoked with (err, [results]);5630* @returns {Promise} a promise, if no callback is passed5631* @example5632*5633* var count = 0;5634* async.whilst(5635* function test(cb) { cb(null, count < 5); },5636* function iter(callback) {5637* count++;5638* setTimeout(function() {5639* callback(null, count);5640* }, 1000);5641* },5642* function (err, n) {5643* // 5 seconds have passed, n = 55644* }5645* );5646*/5647function whilst(test, iteratee, callback) {5648callback = onlyOnce(callback);5649var _fn = wrapAsync(iteratee);5650var _test = wrapAsync(test);5651var results = [];56525653function next(err, ...rest) {5654if (err) return callback(err);5655results = rest;5656if (err === false) return;5657_test(check);5658}56595660function check(err, truth) {5661if (err) return callback(err);5662if (err === false) return;5663if (!truth) return callback(null, ...results);5664_fn(next);5665}56665667return _test(check);5668}5669var whilst$1 = awaitify(whilst, 3);56705671/**5672* Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when5673* stopped, or an error occurs. `callback` will be passed an error and any5674* arguments passed to the final `iteratee`'s callback.5675*5676* The inverse of [whilst]{@link module:ControlFlow.whilst}.5677*5678* @name until5679* @static5680* @memberOf module:ControlFlow5681* @method5682* @see [async.whilst]{@link module:ControlFlow.whilst}5683* @category Control Flow5684* @param {AsyncFunction} test - asynchronous truth test to perform before each5685* execution of `iteratee`. Invoked with (callback).5686* @param {AsyncFunction} iteratee - An async function which is called each time5687* `test` fails. Invoked with (callback).5688* @param {Function} [callback] - A callback which is called after the test5689* function has passed and repeated execution of `iteratee` has stopped. `callback`5690* will be passed an error and any arguments passed to the final `iteratee`'s5691* callback. Invoked with (err, [results]);5692* @returns {Promise} a promise, if a callback is not passed5693*5694* @example5695* const results = []5696* let finished = false5697* async.until(function test(cb) {5698* cb(null, finished)5699* }, function iter(next) {5700* fetchPage(url, (err, body) => {5701* if (err) return next(err)5702* results = results.concat(body.objects)5703* finished = !!body.next5704* next(err)5705* })5706* }, function done (err) {5707* // all pages have been fetched5708* })5709*/5710function until(test, iteratee, callback) {5711const _test = wrapAsync(test);5712return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);5713}57145715/**5716* Runs the `tasks` array of functions in series, each passing their results to5717* the next in the array. However, if any of the `tasks` pass an error to their5718* own callback, the next function is not executed, and the main `callback` is5719* immediately called with the error.5720*5721* @name waterfall5722* @static5723* @memberOf module:ControlFlow5724* @method5725* @category Control Flow5726* @param {Array} tasks - An array of [async functions]{@link AsyncFunction}5727* to run.5728* Each function should complete with any number of `result` values.5729* The `result` values will be passed as arguments, in order, to the next task.5730* @param {Function} [callback] - An optional callback to run once all the5731* functions have completed. This will be passed the results of the last task's5732* callback. Invoked with (err, [results]).5733* @returns undefined5734* @example5735*5736* async.waterfall([5737* function(callback) {5738* callback(null, 'one', 'two');5739* },5740* function(arg1, arg2, callback) {5741* // arg1 now equals 'one' and arg2 now equals 'two'5742* callback(null, 'three');5743* },5744* function(arg1, callback) {5745* // arg1 now equals 'three'5746* callback(null, 'done');5747* }5748* ], function (err, result) {5749* // result now equals 'done'5750* });5751*5752* // Or, with named functions:5753* async.waterfall([5754* myFirstFunction,5755* mySecondFunction,5756* myLastFunction,5757* ], function (err, result) {5758* // result now equals 'done'5759* });5760* function myFirstFunction(callback) {5761* callback(null, 'one', 'two');5762* }5763* function mySecondFunction(arg1, arg2, callback) {5764* // arg1 now equals 'one' and arg2 now equals 'two'5765* callback(null, 'three');5766* }5767* function myLastFunction(arg1, callback) {5768* // arg1 now equals 'three'5769* callback(null, 'done');5770* }5771*/5772function waterfall (tasks, callback) {5773callback = once(callback);5774if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));5775if (!tasks.length) return callback();5776var taskIndex = 0;57775778function nextTask(args) {5779var task = wrapAsync(tasks[taskIndex++]);5780task(...args, onlyOnce(next));5781}57825783function next(err, ...args) {5784if (err === false) return5785if (err || taskIndex === tasks.length) {5786return callback(err, ...args);5787}5788nextTask(args);5789}57905791nextTask([]);5792}57935794var waterfall$1 = awaitify(waterfall);57955796/**5797* An "async function" in the context of Async is an asynchronous function with5798* a variable number of parameters, with the final parameter being a callback.5799* (`function (arg1, arg2, ..., callback) {}`)5800* The final callback is of the form `callback(err, results...)`, which must be5801* called once the function is completed. The callback should be called with a5802* Error as its first argument to signal that an error occurred.5803* Otherwise, if no error occurred, it should be called with `null` as the first5804* argument, and any additional `result` arguments that may apply, to signal5805* successful completion.5806* The callback must be called exactly once, ideally on a later tick of the5807* JavaScript event loop.5808*5809* This type of function is also referred to as a "Node-style async function",5810* or a "continuation passing-style function" (CPS). Most of the methods of this5811* library are themselves CPS/Node-style async functions, or functions that5812* return CPS/Node-style async functions.5813*5814* Wherever we accept a Node-style async function, we also directly accept an5815* [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.5816* In this case, the `async` function will not be passed a final callback5817* argument, and any thrown error will be used as the `err` argument of the5818* implicit callback, and the return value will be used as the `result` value.5819* (i.e. a `rejected` of the returned Promise becomes the `err` callback5820* argument, and a `resolved` value becomes the `result`.)5821*5822* Note, due to JavaScript limitations, we can only detect native `async`5823* functions and not transpilied implementations.5824* Your environment must have `async`/`await` support for this to work.5825* (e.g. Node > v7.6, or a recent version of a modern browser).5826* If you are using `async` functions through a transpiler (e.g. Babel), you5827* must still wrap the function with [asyncify]{@link module:Utils.asyncify},5828* because the `async function` will be compiled to an ordinary function that5829* returns a promise.5830*5831* @typedef {Function} AsyncFunction5832* @static5833*/58345835var index = {5836apply,5837applyEach: applyEach$1,5838applyEachSeries,5839asyncify,5840auto,5841autoInject,5842cargo,5843cargoQueue: cargo$1,5844compose,5845concat: concat$1,5846concatLimit: concatLimit$1,5847concatSeries: concatSeries$1,5848constant,5849detect: detect$1,5850detectLimit: detectLimit$1,5851detectSeries: detectSeries$1,5852dir,5853doUntil,5854doWhilst: doWhilst$1,5855each,5856eachLimit: eachLimit$2,5857eachOf: eachOf$1,5858eachOfLimit: eachOfLimit$2,5859eachOfSeries: eachOfSeries$1,5860eachSeries: eachSeries$1,5861ensureAsync,5862every: every$1,5863everyLimit: everyLimit$1,5864everySeries: everySeries$1,5865filter: filter$1,5866filterLimit: filterLimit$1,5867filterSeries: filterSeries$1,5868forever: forever$1,5869groupBy,5870groupByLimit: groupByLimit$1,5871groupBySeries,5872log,5873map: map$1,5874mapLimit: mapLimit$1,5875mapSeries: mapSeries$1,5876mapValues,5877mapValuesLimit: mapValuesLimit$1,5878mapValuesSeries,5879memoize,5880nextTick,5881parallel,5882parallelLimit,5883priorityQueue,5884queue: queue$1,5885race: race$1,5886reduce: reduce$1,5887reduceRight,5888reflect,5889reflectAll,5890reject: reject$2,5891rejectLimit: rejectLimit$1,5892rejectSeries: rejectSeries$1,5893retry,5894retryable,5895seq,5896series,5897setImmediate: setImmediate$1,5898some: some$1,5899someLimit: someLimit$1,5900someSeries: someSeries$1,5901sortBy: sortBy$1,5902timeout,5903times,5904timesLimit,5905timesSeries,5906transform,5907tryEach: tryEach$1,5908unmemoize,5909until,5910waterfall: waterfall$1,5911whilst: whilst$1,59125913// aliases5914all: every$1,5915allLimit: everyLimit$1,5916allSeries: everySeries$1,5917any: some$1,5918anyLimit: someLimit$1,5919anySeries: someSeries$1,5920find: detect$1,5921findLimit: detectLimit$1,5922findSeries: detectSeries$1,5923flatMap: concat$1,5924flatMapLimit: concatLimit$1,5925flatMapSeries: concatSeries$1,5926forEach: each,5927forEachSeries: eachSeries$1,5928forEachLimit: eachLimit$2,5929forEachOf: eachOf$1,5930forEachOfSeries: eachOfSeries$1,5931forEachOfLimit: eachOfLimit$2,5932inject: reduce$1,5933foldl: reduce$1,5934foldr: reduceRight,5935select: filter$1,5936selectLimit: filterLimit$1,5937selectSeries: filterSeries$1,5938wrapSync: asyncify,5939during: whilst$1,5940doDuring: doWhilst$15941};59425943export default index;5944export { apply, applyEach$1 as applyEach, applyEachSeries, asyncify, auto, autoInject, cargo, cargo$1 as cargoQueue, compose, concat$1 as concat, concatLimit$1 as concatLimit, concatSeries$1 as concatSeries, constant, detect$1 as detect, detectLimit$1 as detectLimit, detectSeries$1 as detectSeries, dir, doUntil, doWhilst$1 as doWhilst, each, eachLimit$2 as eachLimit, eachOf$1 as eachOf, eachOfLimit$2 as eachOfLimit, eachOfSeries$1 as eachOfSeries, eachSeries$1 as eachSeries, ensureAsync, every$1 as every, everyLimit$1 as everyLimit, everySeries$1 as everySeries, filter$1 as filter, filterLimit$1 as filterLimit, filterSeries$1 as filterSeries, forever$1 as forever, groupBy, groupByLimit$1 as groupByLimit, groupBySeries, log, map$1 as map, mapLimit$1 as mapLimit, mapSeries$1 as mapSeries, mapValues, mapValuesLimit$1 as mapValuesLimit, mapValuesSeries, memoize, nextTick, parallel, parallelLimit, priorityQueue, queue$1 as queue, race$1 as race, reduce$1 as reduce, reduceRight, reflect, reflectAll, reject$2 as reject, rejectLimit$1 as rejectLimit, rejectSeries$1 as rejectSeries, retry, retryable, seq, series, setImmediate$1 as setImmediate, some$1 as some, someLimit$1 as someLimit, someSeries$1 as someSeries, sortBy$1 as sortBy, timeout, times, timesLimit, timesSeries, transform, tryEach$1 as tryEach, unmemoize, until, waterfall$1 as waterfall, whilst$1 as whilst, every$1 as all, everyLimit$1 as allLimit, everySeries$1 as allSeries, some$1 as any, someLimit$1 as anyLimit, someSeries$1 as anySeries, detect$1 as find, detectLimit$1 as findLimit, detectSeries$1 as findSeries, concat$1 as flatMap, concatLimit$1 as flatMapLimit, concatSeries$1 as flatMapSeries, each as forEach, eachSeries$1 as forEachSeries, eachLimit$2 as forEachLimit, eachOf$1 as forEachOf, eachOfSeries$1 as forEachOfSeries, eachOfLimit$2 as forEachOfLimit, reduce$1 as inject, reduce$1 as foldl, reduceRight as foldr, filter$1 as select, filterLimit$1 as selectLimit, filterSeries$1 as selectSeries, asyncify as wrapSync, whilst$1 as during, doWhilst$1 as doDuring };594559465947