Path: blob/master/node_modules/async/dist/async.js
2591 views
(function (global, factory) {1typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :2typeof define === 'function' && define.amd ? define(['exports'], factory) :3(factory((global.async = {})));4}(this, (function (exports) { 'use strict';56/**7* Creates a continuation function with some arguments already applied.8*9* Useful as a shorthand when combined with other control flow functions. Any10* arguments passed to the returned function are added to the arguments11* originally passed to apply.12*13* @name apply14* @static15* @memberOf module:Utils16* @method17* @category Util18* @param {Function} fn - The function you want to eventually apply all19* arguments to. Invokes with (arguments...).20* @param {...*} arguments... - Any number of arguments to automatically apply21* when the continuation is called.22* @returns {Function} the partially-applied function23* @example24*25* // using apply26* async.parallel([27* async.apply(fs.writeFile, 'testfile1', 'test1'),28* async.apply(fs.writeFile, 'testfile2', 'test2')29* ]);30*31*32* // the same process without using apply33* async.parallel([34* function(callback) {35* fs.writeFile('testfile1', 'test1', callback);36* },37* function(callback) {38* fs.writeFile('testfile2', 'test2', callback);39* }40* ]);41*42* // It's possible to pass any number of additional arguments when calling the43* // continuation:44*45* node> var fn = async.apply(sys.puts, 'one');46* node> fn('two', 'three');47* one48* two49* three50*/51function apply(fn, ...args) {52return (...callArgs) => fn(...args,...callArgs);53}5455function initialParams (fn) {56return function (...args/*, callback*/) {57var callback = args.pop();58return fn.call(this, args, callback);59};60}6162/* istanbul ignore file */6364var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;65var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;66var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';6768function fallback(fn) {69setTimeout(fn, 0);70}7172function wrap(defer) {73return (fn, ...args) => defer(() => fn(...args));74}7576var _defer;7778if (hasQueueMicrotask) {79_defer = queueMicrotask;80} else if (hasSetImmediate) {81_defer = setImmediate;82} else if (hasNextTick) {83_defer = process.nextTick;84} else {85_defer = fallback;86}8788var setImmediate$1 = wrap(_defer);8990/**91* Take a sync function and make it async, passing its return value to a92* callback. This is useful for plugging sync functions into a waterfall,93* series, or other async functions. Any arguments passed to the generated94* function will be passed to the wrapped function (except for the final95* callback argument). Errors thrown will be passed to the callback.96*97* If the function passed to `asyncify` returns a Promise, that promises's98* resolved/rejected state will be used to call the callback, rather than simply99* the synchronous return value.100*101* This also means you can asyncify ES2017 `async` functions.102*103* @name asyncify104* @static105* @memberOf module:Utils106* @method107* @alias wrapSync108* @category Util109* @param {Function} func - The synchronous function, or Promise-returning110* function to convert to an {@link AsyncFunction}.111* @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be112* invoked with `(args..., callback)`.113* @example114*115* // passing a regular synchronous function116* async.waterfall([117* async.apply(fs.readFile, filename, "utf8"),118* async.asyncify(JSON.parse),119* function (data, next) {120* // data is the result of parsing the text.121* // If there was a parsing error, it would have been caught.122* }123* ], callback);124*125* // passing a function returning a promise126* async.waterfall([127* async.apply(fs.readFile, filename, "utf8"),128* async.asyncify(function (contents) {129* return db.model.create(contents);130* }),131* function (model, next) {132* // `model` is the instantiated model object.133* // If there was an error, this function would be skipped.134* }135* ], callback);136*137* // es2017 example, though `asyncify` is not needed if your JS environment138* // supports async functions out of the box139* var q = async.queue(async.asyncify(async function(file) {140* var intermediateStep = await processFile(file);141* return await somePromise(intermediateStep)142* }));143*144* q.push(files);145*/146function asyncify(func) {147if (isAsync(func)) {148return function (...args/*, callback*/) {149const callback = args.pop();150const promise = func.apply(this, args);151return handlePromise(promise, callback)152}153}154155return initialParams(function (args, callback) {156var result;157try {158result = func.apply(this, args);159} catch (e) {160return callback(e);161}162// if result is Promise object163if (result && typeof result.then === 'function') {164return handlePromise(result, callback)165} else {166callback(null, result);167}168});169}170171function handlePromise(promise, callback) {172return promise.then(value => {173invokeCallback(callback, null, value);174}, err => {175invokeCallback(callback, err && err.message ? err : new Error(err));176});177}178179function invokeCallback(callback, error, value) {180try {181callback(error, value);182} catch (err) {183setImmediate$1(e => { throw e }, err);184}185}186187function isAsync(fn) {188return fn[Symbol.toStringTag] === 'AsyncFunction';189}190191function isAsyncGenerator(fn) {192return fn[Symbol.toStringTag] === 'AsyncGenerator';193}194195function isAsyncIterable(obj) {196return typeof obj[Symbol.asyncIterator] === 'function';197}198199function wrapAsync(asyncFn) {200if (typeof asyncFn !== 'function') throw new Error('expected a function')201return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;202}203204// conditionally promisify a function.205// only return a promise if a callback is omitted206function awaitify (asyncFn, arity = asyncFn.length) {207if (!arity) throw new Error('arity is undefined')208function awaitable (...args) {209if (typeof args[arity - 1] === 'function') {210return asyncFn.apply(this, args)211}212213return new Promise((resolve, reject) => {214args[arity - 1] = (err, ...cbArgs) => {215if (err) return reject(err)216resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);217};218asyncFn.apply(this, args);219})220}221222return awaitable223}224225function applyEach (eachfn) {226return function applyEach(fns, ...callArgs) {227const go = awaitify(function (callback) {228var that = this;229return eachfn(fns, (fn, cb) => {230wrapAsync(fn).apply(that, callArgs.concat(cb));231}, callback);232});233return go;234};235}236237function _asyncMap(eachfn, arr, iteratee, callback) {238arr = arr || [];239var results = [];240var counter = 0;241var _iteratee = wrapAsync(iteratee);242243return eachfn(arr, (value, _, iterCb) => {244var index = counter++;245_iteratee(value, (err, v) => {246results[index] = v;247iterCb(err);248});249}, err => {250callback(err, results);251});252}253254function isArrayLike(value) {255return value &&256typeof value.length === 'number' &&257value.length >= 0 &&258value.length % 1 === 0;259}260261// A temporary value used to identify if the loop should be broken.262// See #1064, #1293263const breakLoop = {};264265function once(fn) {266function wrapper (...args) {267if (fn === null) return;268var callFn = fn;269fn = null;270callFn.apply(this, args);271}272Object.assign(wrapper, fn);273return wrapper274}275276function getIterator (coll) {277return coll[Symbol.iterator] && coll[Symbol.iterator]();278}279280function createArrayIterator(coll) {281var i = -1;282var len = coll.length;283return function next() {284return ++i < len ? {value: coll[i], key: i} : null;285}286}287288function createES2015Iterator(iterator) {289var i = -1;290return function next() {291var item = iterator.next();292if (item.done)293return null;294i++;295return {value: item.value, key: i};296}297}298299function createObjectIterator(obj) {300var okeys = obj ? Object.keys(obj) : [];301var i = -1;302var len = okeys.length;303return function next() {304var key = okeys[++i];305if (key === '__proto__') {306return next();307}308return i < len ? {value: obj[key], key} : null;309};310}311312function createIterator(coll) {313if (isArrayLike(coll)) {314return createArrayIterator(coll);315}316317var iterator = getIterator(coll);318return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);319}320321function onlyOnce(fn) {322return function (...args) {323if (fn === null) throw new Error("Callback was already called.");324var callFn = fn;325fn = null;326callFn.apply(this, args);327};328}329330// for async generators331function asyncEachOfLimit(generator, limit, iteratee, callback) {332let done = false;333let canceled = false;334let awaiting = false;335let running = 0;336let idx = 0;337338function replenish() {339//console.log('replenish')340if (running >= limit || awaiting || done) return341//console.log('replenish awaiting')342awaiting = true;343generator.next().then(({value, done: iterDone}) => {344//console.log('got value', value)345if (canceled || done) return346awaiting = false;347if (iterDone) {348done = true;349if (running <= 0) {350//console.log('done nextCb')351callback(null);352}353return;354}355running++;356iteratee(value, idx, iterateeCallback);357idx++;358replenish();359}).catch(handleError);360}361362function iterateeCallback(err, result) {363//console.log('iterateeCallback')364running -= 1;365if (canceled) return366if (err) return handleError(err)367368if (err === false) {369done = true;370canceled = true;371return372}373374if (result === breakLoop || (done && running <= 0)) {375done = true;376//console.log('done iterCb')377return callback(null);378}379replenish();380}381382function handleError(err) {383if (canceled) return384awaiting = false;385done = true;386callback(err);387}388389replenish();390}391392var eachOfLimit = (limit) => {393return (obj, iteratee, callback) => {394callback = once(callback);395if (limit <= 0) {396throw new RangeError('concurrency limit cannot be less than 1')397}398if (!obj) {399return callback(null);400}401if (isAsyncGenerator(obj)) {402return asyncEachOfLimit(obj, limit, iteratee, callback)403}404if (isAsyncIterable(obj)) {405return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)406}407var nextElem = createIterator(obj);408var done = false;409var canceled = false;410var running = 0;411var looping = false;412413function iterateeCallback(err, value) {414if (canceled) return415running -= 1;416if (err) {417done = true;418callback(err);419}420else if (err === false) {421done = true;422canceled = true;423}424else if (value === breakLoop || (done && running <= 0)) {425done = true;426return callback(null);427}428else if (!looping) {429replenish();430}431}432433function replenish () {434looping = true;435while (running < limit && !done) {436var elem = nextElem();437if (elem === null) {438done = true;439if (running <= 0) {440callback(null);441}442return;443}444running += 1;445iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));446}447looping = false;448}449450replenish();451};452};453454/**455* The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a456* time.457*458* @name eachOfLimit459* @static460* @memberOf module:Collections461* @method462* @see [async.eachOf]{@link module:Collections.eachOf}463* @alias forEachOfLimit464* @category Collection465* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.466* @param {number} limit - The maximum number of async operations at a time.467* @param {AsyncFunction} iteratee - An async function to apply to each468* item in `coll`. The `key` is the item's key, or index in the case of an469* array.470* Invoked with (item, key, callback).471* @param {Function} [callback] - A callback which is called when all472* `iteratee` functions have finished, or an error occurs. Invoked with (err).473* @returns {Promise} a promise, if a callback is omitted474*/475function eachOfLimit$1(coll, limit, iteratee, callback) {476return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);477}478479var eachOfLimit$2 = awaitify(eachOfLimit$1, 4);480481// eachOf implementation optimized for array-likes482function eachOfArrayLike(coll, iteratee, callback) {483callback = once(callback);484var index = 0,485completed = 0,486{length} = coll,487canceled = false;488if (length === 0) {489callback(null);490}491492function iteratorCallback(err, value) {493if (err === false) {494canceled = true;495}496if (canceled === true) return497if (err) {498callback(err);499} else if ((++completed === length) || value === breakLoop) {500callback(null);501}502}503504for (; index < length; index++) {505iteratee(coll[index], index, onlyOnce(iteratorCallback));506}507}508509// a generic version of eachOf which can handle array, object, and iterator cases.510function eachOfGeneric (coll, iteratee, callback) {511return eachOfLimit$2(coll, Infinity, iteratee, callback);512}513514/**515* Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument516* to the iteratee.517*518* @name eachOf519* @static520* @memberOf module:Collections521* @method522* @alias forEachOf523* @category Collection524* @see [async.each]{@link module:Collections.each}525* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.526* @param {AsyncFunction} iteratee - A function to apply to each527* item in `coll`.528* The `key` is the item's key, or index in the case of an array.529* Invoked with (item, key, callback).530* @param {Function} [callback] - A callback which is called when all531* `iteratee` functions have finished, or an error occurs. Invoked with (err).532* @returns {Promise} a promise, if a callback is omitted533* @example534*535* // dev.json is a file containing a valid json object config for dev environment536* // dev.json is a file containing a valid json object config for test environment537* // prod.json is a file containing a valid json object config for prod environment538* // invalid.json is a file with a malformed json object539*540* let configs = {}; //global variable541* let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};542* let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};543*544* // asynchronous function that reads a json file and parses the contents as json object545* function parseFile(file, key, callback) {546* fs.readFile(file, "utf8", function(err, data) {547* if (err) return calback(err);548* try {549* configs[key] = JSON.parse(data);550* } catch (e) {551* return callback(e);552* }553* callback();554* });555* }556*557* // Using callbacks558* async.forEachOf(validConfigFileMap, parseFile, function (err) {559* if (err) {560* console.error(err);561* } else {562* console.log(configs);563* // configs is now a map of JSON data, e.g.564* // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}565* }566* });567*568* //Error handing569* async.forEachOf(invalidConfigFileMap, parseFile, function (err) {570* if (err) {571* console.error(err);572* // JSON parse error exception573* } else {574* console.log(configs);575* }576* });577*578* // Using Promises579* async.forEachOf(validConfigFileMap, parseFile)580* .then( () => {581* console.log(configs);582* // configs is now a map of JSON data, e.g.583* // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}584* }).catch( err => {585* console.error(err);586* });587*588* //Error handing589* async.forEachOf(invalidConfigFileMap, parseFile)590* .then( () => {591* console.log(configs);592* }).catch( err => {593* console.error(err);594* // JSON parse error exception595* });596*597* // Using async/await598* async () => {599* try {600* let result = await async.forEachOf(validConfigFileMap, parseFile);601* console.log(configs);602* // configs is now a map of JSON data, e.g.603* // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}604* }605* catch (err) {606* console.log(err);607* }608* }609*610* //Error handing611* async () => {612* try {613* let result = await async.forEachOf(invalidConfigFileMap, parseFile);614* console.log(configs);615* }616* catch (err) {617* console.log(err);618* // JSON parse error exception619* }620* }621*622*/623function eachOf(coll, iteratee, callback) {624var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;625return eachOfImplementation(coll, wrapAsync(iteratee), callback);626}627628var eachOf$1 = awaitify(eachOf, 3);629630/**631* Produces a new collection of values by mapping each value in `coll` through632* the `iteratee` function. The `iteratee` is called with an item from `coll`633* and a callback for when it has finished processing. Each of these callbacks634* takes 2 arguments: an `error`, and the transformed item from `coll`. If635* `iteratee` passes an error to its callback, the main `callback` (for the636* `map` function) is immediately called with the error.637*638* Note, that since this function applies the `iteratee` to each item in639* parallel, there is no guarantee that the `iteratee` functions will complete640* in order. However, the results array will be in the same order as the641* original `coll`.642*643* If `map` is passed an Object, the results will be an Array. The results644* will roughly be in the order of the original Objects' keys (but this can645* vary across JavaScript engines).646*647* @name map648* @static649* @memberOf module:Collections650* @method651* @category Collection652* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.653* @param {AsyncFunction} iteratee - An async function to apply to each item in654* `coll`.655* The iteratee should complete with the transformed item.656* Invoked with (item, callback).657* @param {Function} [callback] - A callback which is called when all `iteratee`658* functions have finished, or an error occurs. Results is an Array of the659* transformed items from the `coll`. Invoked with (err, results).660* @returns {Promise} a promise, if no callback is passed661* @example662*663* // file1.txt is a file that is 1000 bytes in size664* // file2.txt is a file that is 2000 bytes in size665* // file3.txt is a file that is 3000 bytes in size666* // file4.txt does not exist667*668* const fileList = ['file1.txt','file2.txt','file3.txt'];669* const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];670*671* // asynchronous function that returns the file size in bytes672* function getFileSizeInBytes(file, callback) {673* fs.stat(file, function(err, stat) {674* if (err) {675* return callback(err);676* }677* callback(null, stat.size);678* });679* }680*681* // Using callbacks682* async.map(fileList, getFileSizeInBytes, function(err, results) {683* if (err) {684* console.log(err);685* } else {686* console.log(results);687* // results is now an array of the file size in bytes for each file, e.g.688* // [ 1000, 2000, 3000]689* }690* });691*692* // Error Handling693* async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {694* if (err) {695* console.log(err);696* // [ Error: ENOENT: no such file or directory ]697* } else {698* console.log(results);699* }700* });701*702* // Using Promises703* async.map(fileList, getFileSizeInBytes)704* .then( results => {705* console.log(results);706* // results is now an array of the file size in bytes for each file, e.g.707* // [ 1000, 2000, 3000]708* }).catch( err => {709* console.log(err);710* });711*712* // Error Handling713* async.map(withMissingFileList, getFileSizeInBytes)714* .then( results => {715* console.log(results);716* }).catch( err => {717* console.log(err);718* // [ Error: ENOENT: no such file or directory ]719* });720*721* // Using async/await722* async () => {723* try {724* let results = await async.map(fileList, getFileSizeInBytes);725* console.log(results);726* // results is now an array of the file size in bytes for each file, e.g.727* // [ 1000, 2000, 3000]728* }729* catch (err) {730* console.log(err);731* }732* }733*734* // Error Handling735* async () => {736* try {737* let results = await async.map(withMissingFileList, getFileSizeInBytes);738* console.log(results);739* }740* catch (err) {741* console.log(err);742* // [ Error: ENOENT: no such file or directory ]743* }744* }745*746*/747function map (coll, iteratee, callback) {748return _asyncMap(eachOf$1, coll, iteratee, callback)749}750var map$1 = awaitify(map, 3);751752/**753* Applies the provided arguments to each function in the array, calling754* `callback` after all functions have completed. If you only provide the first755* argument, `fns`, then it will return a function which lets you pass in the756* arguments as if it were a single function call. If more arguments are757* provided, `callback` is required while `args` is still optional. The results758* for each of the applied async functions are passed to the final callback759* as an array.760*761* @name applyEach762* @static763* @memberOf module:ControlFlow764* @method765* @category Control Flow766* @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s767* to all call with the same arguments768* @param {...*} [args] - any number of separate arguments to pass to the769* function.770* @param {Function} [callback] - the final argument should be the callback,771* called when all functions have completed processing.772* @returns {AsyncFunction} - Returns a function that takes no args other than773* an optional callback, that is the result of applying the `args` to each774* of the functions.775* @example776*777* const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')778*779* appliedFn((err, results) => {780* // results[0] is the results for `enableSearch`781* // results[1] is the results for `updateSchema`782* });783*784* // partial application example:785* async.each(786* buckets,787* async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),788* callback789* );790*/791var applyEach$1 = applyEach(map$1);792793/**794* The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.795*796* @name eachOfSeries797* @static798* @memberOf module:Collections799* @method800* @see [async.eachOf]{@link module:Collections.eachOf}801* @alias forEachOfSeries802* @category Collection803* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.804* @param {AsyncFunction} iteratee - An async function to apply to each item in805* `coll`.806* Invoked with (item, key, callback).807* @param {Function} [callback] - A callback which is called when all `iteratee`808* functions have finished, or an error occurs. Invoked with (err).809* @returns {Promise} a promise, if a callback is omitted810*/811function eachOfSeries(coll, iteratee, callback) {812return eachOfLimit$2(coll, 1, iteratee, callback)813}814var eachOfSeries$1 = awaitify(eachOfSeries, 3);815816/**817* The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.818*819* @name mapSeries820* @static821* @memberOf module:Collections822* @method823* @see [async.map]{@link module:Collections.map}824* @category Collection825* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.826* @param {AsyncFunction} iteratee - An async function to apply to each item in827* `coll`.828* The iteratee should complete with the transformed item.829* Invoked with (item, callback).830* @param {Function} [callback] - A callback which is called when all `iteratee`831* functions have finished, or an error occurs. Results is an array of the832* transformed items from the `coll`. Invoked with (err, results).833* @returns {Promise} a promise, if no callback is passed834*/835function mapSeries (coll, iteratee, callback) {836return _asyncMap(eachOfSeries$1, coll, iteratee, callback)837}838var mapSeries$1 = awaitify(mapSeries, 3);839840/**841* The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.842*843* @name applyEachSeries844* @static845* @memberOf module:ControlFlow846* @method847* @see [async.applyEach]{@link module:ControlFlow.applyEach}848* @category Control Flow849* @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all850* call with the same arguments851* @param {...*} [args] - any number of separate arguments to pass to the852* function.853* @param {Function} [callback] - the final argument should be the callback,854* called when all functions have completed processing.855* @returns {AsyncFunction} - A function, that when called, is the result of856* appling the `args` to the list of functions. It takes no args, other than857* a callback.858*/859var applyEachSeries = applyEach(mapSeries$1);860861const PROMISE_SYMBOL = Symbol('promiseCallback');862863function promiseCallback () {864let resolve, reject;865function callback (err, ...args) {866if (err) return reject(err)867resolve(args.length > 1 ? args : args[0]);868}869870callback[PROMISE_SYMBOL] = new Promise((res, rej) => {871resolve = res,872reject = rej;873});874875return callback876}877878/**879* Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on880* their requirements. Each function can optionally depend on other functions881* being completed first, and each function is run as soon as its requirements882* are satisfied.883*884* If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence885* will stop. Further tasks will not execute (so any other functions depending886* on it will not run), and the main `callback` is immediately called with the887* error.888*889* {@link AsyncFunction}s also receive an object containing the results of functions which890* have completed so far as the first argument, if they have dependencies. If a891* task function has no dependencies, it will only be passed a callback.892*893* @name auto894* @static895* @memberOf module:ControlFlow896* @method897* @category Control Flow898* @param {Object} tasks - An object. Each of its properties is either a899* function or an array of requirements, with the {@link AsyncFunction} itself the last item900* in the array. The object's key of a property serves as the name of the task901* defined by that property, i.e. can be used when specifying requirements for902* other tasks. The function receives one or two arguments:903* * a `results` object, containing the results of the previously executed904* functions, only passed if the task has any dependencies,905* * a `callback(err, result)` function, which must be called when finished,906* passing an `error` (which can be `null`) and the result of the function's907* execution.908* @param {number} [concurrency=Infinity] - An optional `integer` for909* determining the maximum number of tasks that can be run in parallel. By910* default, as many as possible.911* @param {Function} [callback] - An optional callback which is called when all912* the tasks have been completed. It receives the `err` argument if any `tasks`913* pass an error to their callback. Results are always returned; however, if an914* error occurs, no further `tasks` will be performed, and the results object915* will only contain partial results. Invoked with (err, results).916* @returns {Promise} a promise, if a callback is not passed917* @example918*919* //Using Callbacks920* async.auto({921* get_data: function(callback) {922* // async code to get some data923* callback(null, 'data', 'converted to array');924* },925* make_folder: function(callback) {926* // async code to create a directory to store a file in927* // this is run at the same time as getting the data928* callback(null, 'folder');929* },930* write_file: ['get_data', 'make_folder', function(results, callback) {931* // once there is some data and the directory exists,932* // write the data to a file in the directory933* callback(null, 'filename');934* }],935* email_link: ['write_file', function(results, callback) {936* // once the file is written let's email a link to it...937* callback(null, {'file':results.write_file, 'email':'[email protected]'});938* }]939* }, function(err, results) {940* if (err) {941* console.log('err = ', err);942* }943* console.log('results = ', results);944* // results = {945* // get_data: ['data', 'converted to array']946* // make_folder; 'folder',947* // write_file: 'filename'948* // email_link: { file: 'filename', email: '[email protected]' }949* // }950* });951*952* //Using Promises953* async.auto({954* get_data: function(callback) {955* console.log('in get_data');956* // async code to get some data957* callback(null, 'data', 'converted to array');958* },959* make_folder: function(callback) {960* console.log('in make_folder');961* // async code to create a directory to store a file in962* // this is run at the same time as getting the data963* callback(null, 'folder');964* },965* write_file: ['get_data', 'make_folder', function(results, callback) {966* // once there is some data and the directory exists,967* // write the data to a file in the directory968* callback(null, 'filename');969* }],970* email_link: ['write_file', function(results, callback) {971* // once the file is written let's email a link to it...972* callback(null, {'file':results.write_file, 'email':'[email protected]'});973* }]974* }).then(results => {975* console.log('results = ', results);976* // results = {977* // get_data: ['data', 'converted to array']978* // make_folder; 'folder',979* // write_file: 'filename'980* // email_link: { file: 'filename', email: '[email protected]' }981* // }982* }).catch(err => {983* console.log('err = ', err);984* });985*986* //Using async/await987* async () => {988* try {989* let results = await async.auto({990* get_data: function(callback) {991* // async code to get some data992* callback(null, 'data', 'converted to array');993* },994* make_folder: function(callback) {995* // async code to create a directory to store a file in996* // this is run at the same time as getting the data997* callback(null, 'folder');998* },999* write_file: ['get_data', 'make_folder', function(results, callback) {1000* // once there is some data and the directory exists,1001* // write the data to a file in the directory1002* callback(null, 'filename');1003* }],1004* email_link: ['write_file', function(results, callback) {1005* // once the file is written let's email a link to it...1006* callback(null, {'file':results.write_file, 'email':'[email protected]'});1007* }]1008* });1009* console.log('results = ', results);1010* // results = {1011* // get_data: ['data', 'converted to array']1012* // make_folder; 'folder',1013* // write_file: 'filename'1014* // email_link: { file: 'filename', email: '[email protected]' }1015* // }1016* }1017* catch (err) {1018* console.log(err);1019* }1020* }1021*1022*/1023function auto(tasks, concurrency, callback) {1024if (typeof concurrency !== 'number') {1025// concurrency is optional, shift the args.1026callback = concurrency;1027concurrency = null;1028}1029callback = once(callback || promiseCallback());1030var numTasks = Object.keys(tasks).length;1031if (!numTasks) {1032return callback(null);1033}1034if (!concurrency) {1035concurrency = numTasks;1036}10371038var results = {};1039var runningTasks = 0;1040var canceled = false;1041var hasError = false;10421043var listeners = Object.create(null);10441045var readyTasks = [];10461047// for cycle detection:1048var readyToCheck = []; // tasks that have been identified as reachable1049// without the possibility of returning to an ancestor task1050var uncheckedDependencies = {};10511052Object.keys(tasks).forEach(key => {1053var task = tasks[key];1054if (!Array.isArray(task)) {1055// no dependencies1056enqueueTask(key, [task]);1057readyToCheck.push(key);1058return;1059}10601061var dependencies = task.slice(0, task.length - 1);1062var remainingDependencies = dependencies.length;1063if (remainingDependencies === 0) {1064enqueueTask(key, task);1065readyToCheck.push(key);1066return;1067}1068uncheckedDependencies[key] = remainingDependencies;10691070dependencies.forEach(dependencyName => {1071if (!tasks[dependencyName]) {1072throw new Error('async.auto task `' + key +1073'` has a non-existent dependency `' +1074dependencyName + '` in ' +1075dependencies.join(', '));1076}1077addListener(dependencyName, () => {1078remainingDependencies--;1079if (remainingDependencies === 0) {1080enqueueTask(key, task);1081}1082});1083});1084});10851086checkForDeadlocks();1087processQueue();10881089function enqueueTask(key, task) {1090readyTasks.push(() => runTask(key, task));1091}10921093function processQueue() {1094if (canceled) return1095if (readyTasks.length === 0 && runningTasks === 0) {1096return callback(null, results);1097}1098while(readyTasks.length && runningTasks < concurrency) {1099var run = readyTasks.shift();1100run();1101}11021103}11041105function addListener(taskName, fn) {1106var taskListeners = listeners[taskName];1107if (!taskListeners) {1108taskListeners = listeners[taskName] = [];1109}11101111taskListeners.push(fn);1112}11131114function taskComplete(taskName) {1115var taskListeners = listeners[taskName] || [];1116taskListeners.forEach(fn => fn());1117processQueue();1118}111911201121function runTask(key, task) {1122if (hasError) return;11231124var taskCallback = onlyOnce((err, ...result) => {1125runningTasks--;1126if (err === false) {1127canceled = true;1128return1129}1130if (result.length < 2) {1131[result] = result;1132}1133if (err) {1134var safeResults = {};1135Object.keys(results).forEach(rkey => {1136safeResults[rkey] = results[rkey];1137});1138safeResults[key] = result;1139hasError = true;1140listeners = Object.create(null);1141if (canceled) return1142callback(err, safeResults);1143} else {1144results[key] = result;1145taskComplete(key);1146}1147});11481149runningTasks++;1150var taskFn = wrapAsync(task[task.length - 1]);1151if (task.length > 1) {1152taskFn(results, taskCallback);1153} else {1154taskFn(taskCallback);1155}1156}11571158function checkForDeadlocks() {1159// Kahn's algorithm1160// https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm1161// http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html1162var currentTask;1163var counter = 0;1164while (readyToCheck.length) {1165currentTask = readyToCheck.pop();1166counter++;1167getDependents(currentTask).forEach(dependent => {1168if (--uncheckedDependencies[dependent] === 0) {1169readyToCheck.push(dependent);1170}1171});1172}11731174if (counter !== numTasks) {1175throw new Error(1176'async.auto cannot execute tasks due to a recursive dependency'1177);1178}1179}11801181function getDependents(taskName) {1182var result = [];1183Object.keys(tasks).forEach(key => {1184const task = tasks[key];1185if (Array.isArray(task) && task.indexOf(taskName) >= 0) {1186result.push(key);1187}1188});1189return result;1190}11911192return callback[PROMISE_SYMBOL]1193}11941195var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/;1196var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/;1197var FN_ARG_SPLIT = /,/;1198var FN_ARG = /(=.+)?(\s*)$/;11991200function stripComments(string) {1201let stripped = '';1202let index = 0;1203let endBlockComment = string.indexOf('*/');1204while (index < string.length) {1205if (string[index] === '/' && string[index+1] === '/') {1206// inline comment1207let endIndex = string.indexOf('\n', index);1208index = (endIndex === -1) ? string.length : endIndex;1209} else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) {1210// block comment1211let endIndex = string.indexOf('*/', index);1212if (endIndex !== -1) {1213index = endIndex + 2;1214endBlockComment = string.indexOf('*/', index);1215} else {1216stripped += string[index];1217index++;1218}1219} else {1220stripped += string[index];1221index++;1222}1223}1224return stripped;1225}12261227function parseParams(func) {1228const src = stripComments(func.toString());1229let match = src.match(FN_ARGS);1230if (!match) {1231match = src.match(ARROW_FN_ARGS);1232}1233if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src)1234let [, args] = match;1235return args1236.replace(/\s/g, '')1237.split(FN_ARG_SPLIT)1238.map((arg) => arg.replace(FN_ARG, '').trim());1239}12401241/**1242* A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent1243* tasks are specified as parameters to the function, after the usual callback1244* parameter, with the parameter names matching the names of the tasks it1245* depends on. This can provide even more readable task graphs which can be1246* easier to maintain.1247*1248* If a final callback is specified, the task results are similarly injected,1249* specified as named parameters after the initial error parameter.1250*1251* The autoInject function is purely syntactic sugar and its semantics are1252* otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.1253*1254* @name autoInject1255* @static1256* @memberOf module:ControlFlow1257* @method1258* @see [async.auto]{@link module:ControlFlow.auto}1259* @category Control Flow1260* @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of1261* the form 'func([dependencies...], callback). The object's key of a property1262* serves as the name of the task defined by that property, i.e. can be used1263* when specifying requirements for other tasks.1264* * The `callback` parameter is a `callback(err, result)` which must be called1265* when finished, passing an `error` (which can be `null`) and the result of1266* the function's execution. The remaining parameters name other tasks on1267* which the task is dependent, and the results from those tasks are the1268* arguments of those parameters.1269* @param {Function} [callback] - An optional callback which is called when all1270* the tasks have been completed. It receives the `err` argument if any `tasks`1271* pass an error to their callback, and a `results` object with any completed1272* task results, similar to `auto`.1273* @returns {Promise} a promise, if no callback is passed1274* @example1275*1276* // The example from `auto` can be rewritten as follows:1277* async.autoInject({1278* get_data: function(callback) {1279* // async code to get some data1280* callback(null, 'data', 'converted to array');1281* },1282* make_folder: function(callback) {1283* // async code to create a directory to store a file in1284* // this is run at the same time as getting the data1285* callback(null, 'folder');1286* },1287* write_file: function(get_data, make_folder, callback) {1288* // once there is some data and the directory exists,1289* // write the data to a file in the directory1290* callback(null, 'filename');1291* },1292* email_link: function(write_file, callback) {1293* // once the file is written let's email a link to it...1294* // write_file contains the filename returned by write_file.1295* callback(null, {'file':write_file, 'email':'[email protected]'});1296* }1297* }, function(err, results) {1298* console.log('err = ', err);1299* console.log('email_link = ', results.email_link);1300* });1301*1302* // If you are using a JS minifier that mangles parameter names, `autoInject`1303* // will not work with plain functions, since the parameter names will be1304* // collapsed to a single letter identifier. To work around this, you can1305* // explicitly specify the names of the parameters your task function needs1306* // in an array, similar to Angular.js dependency injection.1307*1308* // This still has an advantage over plain `auto`, since the results a task1309* // depends on are still spread into arguments.1310* async.autoInject({1311* //...1312* write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {1313* callback(null, 'filename');1314* }],1315* email_link: ['write_file', function(write_file, callback) {1316* callback(null, {'file':write_file, 'email':'[email protected]'});1317* }]1318* //...1319* }, function(err, results) {1320* console.log('err = ', err);1321* console.log('email_link = ', results.email_link);1322* });1323*/1324function autoInject(tasks, callback) {1325var newTasks = {};13261327Object.keys(tasks).forEach(key => {1328var taskFn = tasks[key];1329var params;1330var fnIsAsync = isAsync(taskFn);1331var hasNoDeps =1332(!fnIsAsync && taskFn.length === 1) ||1333(fnIsAsync && taskFn.length === 0);13341335if (Array.isArray(taskFn)) {1336params = [...taskFn];1337taskFn = params.pop();13381339newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);1340} else if (hasNoDeps) {1341// no dependencies, use the function as-is1342newTasks[key] = taskFn;1343} else {1344params = parseParams(taskFn);1345if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {1346throw new Error("autoInject task functions require explicit parameters.");1347}13481349// remove callback param1350if (!fnIsAsync) params.pop();13511352newTasks[key] = params.concat(newTask);1353}13541355function newTask(results, taskCb) {1356var newArgs = params.map(name => results[name]);1357newArgs.push(taskCb);1358wrapAsync(taskFn)(...newArgs);1359}1360});13611362return auto(newTasks, callback);1363}13641365// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation1366// used for queues. This implementation assumes that the node provided by the user can be modified1367// to adjust the next and last properties. We implement only the minimal functionality1368// for queue support.1369class DLL {1370constructor() {1371this.head = this.tail = null;1372this.length = 0;1373}13741375removeLink(node) {1376if (node.prev) node.prev.next = node.next;1377else this.head = node.next;1378if (node.next) node.next.prev = node.prev;1379else this.tail = node.prev;13801381node.prev = node.next = null;1382this.length -= 1;1383return node;1384}13851386empty () {1387while(this.head) this.shift();1388return this;1389}13901391insertAfter(node, newNode) {1392newNode.prev = node;1393newNode.next = node.next;1394if (node.next) node.next.prev = newNode;1395else this.tail = newNode;1396node.next = newNode;1397this.length += 1;1398}13991400insertBefore(node, newNode) {1401newNode.prev = node.prev;1402newNode.next = node;1403if (node.prev) node.prev.next = newNode;1404else this.head = newNode;1405node.prev = newNode;1406this.length += 1;1407}14081409unshift(node) {1410if (this.head) this.insertBefore(this.head, node);1411else setInitial(this, node);1412}14131414push(node) {1415if (this.tail) this.insertAfter(this.tail, node);1416else setInitial(this, node);1417}14181419shift() {1420return this.head && this.removeLink(this.head);1421}14221423pop() {1424return this.tail && this.removeLink(this.tail);1425}14261427toArray() {1428return [...this]1429}14301431*[Symbol.iterator] () {1432var cur = this.head;1433while (cur) {1434yield cur.data;1435cur = cur.next;1436}1437}14381439remove (testFn) {1440var curr = this.head;1441while(curr) {1442var {next} = curr;1443if (testFn(curr)) {1444this.removeLink(curr);1445}1446curr = next;1447}1448return this;1449}1450}14511452function setInitial(dll, node) {1453dll.length = 1;1454dll.head = dll.tail = node;1455}14561457function queue(worker, concurrency, payload) {1458if (concurrency == null) {1459concurrency = 1;1460}1461else if(concurrency === 0) {1462throw new RangeError('Concurrency must not be zero');1463}14641465var _worker = wrapAsync(worker);1466var numRunning = 0;1467var workersList = [];1468const events = {1469error: [],1470drain: [],1471saturated: [],1472unsaturated: [],1473empty: []1474};14751476function on (event, handler) {1477events[event].push(handler);1478}14791480function once (event, handler) {1481const handleAndRemove = (...args) => {1482off(event, handleAndRemove);1483handler(...args);1484};1485events[event].push(handleAndRemove);1486}14871488function off (event, handler) {1489if (!event) return Object.keys(events).forEach(ev => events[ev] = [])1490if (!handler) return events[event] = []1491events[event] = events[event].filter(ev => ev !== handler);1492}14931494function trigger (event, ...args) {1495events[event].forEach(handler => handler(...args));1496}14971498var processingScheduled = false;1499function _insert(data, insertAtFront, rejectOnError, callback) {1500if (callback != null && typeof callback !== 'function') {1501throw new Error('task callback must be a function');1502}1503q.started = true;15041505var res, rej;1506function promiseCallback (err, ...args) {1507// we don't care about the error, let the global error handler1508// deal with it1509if (err) return rejectOnError ? rej(err) : res()1510if (args.length <= 1) return res(args[0])1511res(args);1512}15131514var item = {1515data,1516callback: rejectOnError ?1517promiseCallback :1518(callback || promiseCallback)1519};15201521if (insertAtFront) {1522q._tasks.unshift(item);1523} else {1524q._tasks.push(item);1525}15261527if (!processingScheduled) {1528processingScheduled = true;1529setImmediate$1(() => {1530processingScheduled = false;1531q.process();1532});1533}15341535if (rejectOnError || !callback) {1536return new Promise((resolve, reject) => {1537res = resolve;1538rej = reject;1539})1540}1541}15421543function _createCB(tasks) {1544return function (err, ...args) {1545numRunning -= 1;15461547for (var i = 0, l = tasks.length; i < l; i++) {1548var task = tasks[i];15491550var index = workersList.indexOf(task);1551if (index === 0) {1552workersList.shift();1553} else if (index > 0) {1554workersList.splice(index, 1);1555}15561557task.callback(err, ...args);15581559if (err != null) {1560trigger('error', err, task.data);1561}1562}15631564if (numRunning <= (q.concurrency - q.buffer) ) {1565trigger('unsaturated');1566}15671568if (q.idle()) {1569trigger('drain');1570}1571q.process();1572};1573}15741575function _maybeDrain(data) {1576if (data.length === 0 && q.idle()) {1577// call drain immediately if there are no tasks1578setImmediate$1(() => trigger('drain'));1579return true1580}1581return false1582}15831584const eventMethod = (name) => (handler) => {1585if (!handler) {1586return new Promise((resolve, reject) => {1587once(name, (err, data) => {1588if (err) return reject(err)1589resolve(data);1590});1591})1592}1593off(name);1594on(name, handler);15951596};15971598var isProcessing = false;1599var q = {1600_tasks: new DLL(),1601*[Symbol.iterator] () {1602yield* q._tasks[Symbol.iterator]();1603},1604concurrency,1605payload,1606buffer: concurrency / 4,1607started: false,1608paused: false,1609push (data, callback) {1610if (Array.isArray(data)) {1611if (_maybeDrain(data)) return1612return data.map(datum => _insert(datum, false, false, callback))1613}1614return _insert(data, false, false, callback);1615},1616pushAsync (data, callback) {1617if (Array.isArray(data)) {1618if (_maybeDrain(data)) return1619return data.map(datum => _insert(datum, false, true, callback))1620}1621return _insert(data, false, true, callback);1622},1623kill () {1624off();1625q._tasks.empty();1626},1627unshift (data, callback) {1628if (Array.isArray(data)) {1629if (_maybeDrain(data)) return1630return data.map(datum => _insert(datum, true, false, callback))1631}1632return _insert(data, true, false, callback);1633},1634unshiftAsync (data, callback) {1635if (Array.isArray(data)) {1636if (_maybeDrain(data)) return1637return data.map(datum => _insert(datum, true, true, callback))1638}1639return _insert(data, true, true, callback);1640},1641remove (testFn) {1642q._tasks.remove(testFn);1643},1644process () {1645// Avoid trying to start too many processing operations. This can occur1646// when callbacks resolve synchronously (#1267).1647if (isProcessing) {1648return;1649}1650isProcessing = true;1651while(!q.paused && numRunning < q.concurrency && q._tasks.length){1652var tasks = [], data = [];1653var l = q._tasks.length;1654if (q.payload) l = Math.min(l, q.payload);1655for (var i = 0; i < l; i++) {1656var node = q._tasks.shift();1657tasks.push(node);1658workersList.push(node);1659data.push(node.data);1660}16611662numRunning += 1;16631664if (q._tasks.length === 0) {1665trigger('empty');1666}16671668if (numRunning === q.concurrency) {1669trigger('saturated');1670}16711672var cb = onlyOnce(_createCB(tasks));1673_worker(data, cb);1674}1675isProcessing = false;1676},1677length () {1678return q._tasks.length;1679},1680running () {1681return numRunning;1682},1683workersList () {1684return workersList;1685},1686idle() {1687return q._tasks.length + numRunning === 0;1688},1689pause () {1690q.paused = true;1691},1692resume () {1693if (q.paused === false) { return; }1694q.paused = false;1695setImmediate$1(q.process);1696}1697};1698// define these as fixed properties, so people get useful errors when updating1699Object.defineProperties(q, {1700saturated: {1701writable: false,1702value: eventMethod('saturated')1703},1704unsaturated: {1705writable: false,1706value: eventMethod('unsaturated')1707},1708empty: {1709writable: false,1710value: eventMethod('empty')1711},1712drain: {1713writable: false,1714value: eventMethod('drain')1715},1716error: {1717writable: false,1718value: eventMethod('error')1719},1720});1721return q;1722}17231724/**1725* Creates a `cargo` object with the specified payload. Tasks added to the1726* cargo will be processed altogether (up to the `payload` limit). If the1727* `worker` is in progress, the task is queued until it becomes available. Once1728* the `worker` has completed some tasks, each callback of those tasks is1729* called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)1730* for how `cargo` and `queue` work.1731*1732* While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers1733* at a time, cargo passes an array of tasks to a single worker, repeating1734* when the worker is finished.1735*1736* @name cargo1737* @static1738* @memberOf module:ControlFlow1739* @method1740* @see [async.queue]{@link module:ControlFlow.queue}1741* @category Control Flow1742* @param {AsyncFunction} worker - An asynchronous function for processing an array1743* of queued tasks. Invoked with `(tasks, callback)`.1744* @param {number} [payload=Infinity] - An optional `integer` for determining1745* how many tasks should be processed per round; if omitted, the default is1746* unlimited.1747* @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can1748* attached as certain properties to listen for specific events during the1749* lifecycle of the cargo and inner queue.1750* @example1751*1752* // create a cargo object with payload 21753* var cargo = async.cargo(function(tasks, callback) {1754* for (var i=0; i<tasks.length; i++) {1755* console.log('hello ' + tasks[i].name);1756* }1757* callback();1758* }, 2);1759*1760* // add some items1761* cargo.push({name: 'foo'}, function(err) {1762* console.log('finished processing foo');1763* });1764* cargo.push({name: 'bar'}, function(err) {1765* console.log('finished processing bar');1766* });1767* await cargo.push({name: 'baz'});1768* console.log('finished processing baz');1769*/1770function cargo(worker, payload) {1771return queue(worker, 1, payload);1772}17731774/**1775* Creates a `cargoQueue` object with the specified payload. Tasks added to the1776* cargoQueue will be processed together (up to the `payload` limit) in `concurrency` parallel workers.1777* If the all `workers` are in progress, the task is queued until one becomes available. Once1778* a `worker` has completed some tasks, each callback of those tasks is1779* called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)1780* for how `cargo` and `queue` work.1781*1782* While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers1783* at a time, and [`cargo`]{@link module:ControlFlow.cargo} passes an array of tasks to a single worker,1784* the cargoQueue passes an array of tasks to multiple parallel workers.1785*1786* @name cargoQueue1787* @static1788* @memberOf module:ControlFlow1789* @method1790* @see [async.queue]{@link module:ControlFlow.queue}1791* @see [async.cargo]{@link module:ControlFLow.cargo}1792* @category Control Flow1793* @param {AsyncFunction} worker - An asynchronous function for processing an array1794* of queued tasks. Invoked with `(tasks, callback)`.1795* @param {number} [concurrency=1] - An `integer` for determining how many1796* `worker` functions should be run in parallel. If omitted, the concurrency1797* defaults to `1`. If the concurrency is `0`, an error is thrown.1798* @param {number} [payload=Infinity] - An optional `integer` for determining1799* how many tasks should be processed per round; if omitted, the default is1800* unlimited.1801* @returns {module:ControlFlow.QueueObject} A cargoQueue object to manage the tasks. Callbacks can1802* attached as certain properties to listen for specific events during the1803* lifecycle of the cargoQueue and inner queue.1804* @example1805*1806* // create a cargoQueue object with payload 2 and concurrency 21807* var cargoQueue = async.cargoQueue(function(tasks, callback) {1808* for (var i=0; i<tasks.length; i++) {1809* console.log('hello ' + tasks[i].name);1810* }1811* callback();1812* }, 2, 2);1813*1814* // add some items1815* cargoQueue.push({name: 'foo'}, function(err) {1816* console.log('finished processing foo');1817* });1818* cargoQueue.push({name: 'bar'}, function(err) {1819* console.log('finished processing bar');1820* });1821* cargoQueue.push({name: 'baz'}, function(err) {1822* console.log('finished processing baz');1823* });1824* cargoQueue.push({name: 'boo'}, function(err) {1825* console.log('finished processing boo');1826* });1827*/1828function cargo$1(worker, concurrency, payload) {1829return queue(worker, concurrency, payload);1830}18311832/**1833* Reduces `coll` into a single value using an async `iteratee` to return each1834* successive step. `memo` is the initial state of the reduction. This function1835* only operates in series.1836*1837* For performance reasons, it may make sense to split a call to this function1838* into a parallel map, and then use the normal `Array.prototype.reduce` on the1839* results. This function is for situations where each step in the reduction1840* needs to be async; if you can get the data before reducing it, then it's1841* probably a good idea to do so.1842*1843* @name reduce1844* @static1845* @memberOf module:Collections1846* @method1847* @alias inject1848* @alias foldl1849* @category Collection1850* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.1851* @param {*} memo - The initial state of the reduction.1852* @param {AsyncFunction} iteratee - A function applied to each item in the1853* array to produce the next step in the reduction.1854* The `iteratee` should complete with the next state of the reduction.1855* If the iteratee completes with an error, the reduction is stopped and the1856* main `callback` is immediately called with the error.1857* Invoked with (memo, item, callback).1858* @param {Function} [callback] - A callback which is called after all the1859* `iteratee` functions have finished. Result is the reduced value. Invoked with1860* (err, result).1861* @returns {Promise} a promise, if no callback is passed1862* @example1863*1864* // file1.txt is a file that is 1000 bytes in size1865* // file2.txt is a file that is 2000 bytes in size1866* // file3.txt is a file that is 3000 bytes in size1867* // file4.txt does not exist1868*1869* const fileList = ['file1.txt','file2.txt','file3.txt'];1870* const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt'];1871*1872* // asynchronous function that computes the file size in bytes1873* // file size is added to the memoized value, then returned1874* function getFileSizeInBytes(memo, file, callback) {1875* fs.stat(file, function(err, stat) {1876* if (err) {1877* return callback(err);1878* }1879* callback(null, memo + stat.size);1880* });1881* }1882*1883* // Using callbacks1884* async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) {1885* if (err) {1886* console.log(err);1887* } else {1888* console.log(result);1889* // 60001890* // which is the sum of the file sizes of the three files1891* }1892* });1893*1894* // Error Handling1895* async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) {1896* if (err) {1897* console.log(err);1898* // [ Error: ENOENT: no such file or directory ]1899* } else {1900* console.log(result);1901* }1902* });1903*1904* // Using Promises1905* async.reduce(fileList, 0, getFileSizeInBytes)1906* .then( result => {1907* console.log(result);1908* // 60001909* // which is the sum of the file sizes of the three files1910* }).catch( err => {1911* console.log(err);1912* });1913*1914* // Error Handling1915* async.reduce(withMissingFileList, 0, getFileSizeInBytes)1916* .then( result => {1917* console.log(result);1918* }).catch( err => {1919* console.log(err);1920* // [ Error: ENOENT: no such file or directory ]1921* });1922*1923* // Using async/await1924* async () => {1925* try {1926* let result = await async.reduce(fileList, 0, getFileSizeInBytes);1927* console.log(result);1928* // 60001929* // which is the sum of the file sizes of the three files1930* }1931* catch (err) {1932* console.log(err);1933* }1934* }1935*1936* // Error Handling1937* async () => {1938* try {1939* let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);1940* console.log(result);1941* }1942* catch (err) {1943* console.log(err);1944* // [ Error: ENOENT: no such file or directory ]1945* }1946* }1947*1948*/1949function reduce(coll, memo, iteratee, callback) {1950callback = once(callback);1951var _iteratee = wrapAsync(iteratee);1952return eachOfSeries$1(coll, (x, i, iterCb) => {1953_iteratee(memo, x, (err, v) => {1954memo = v;1955iterCb(err);1956});1957}, err => callback(err, memo));1958}1959var reduce$1 = awaitify(reduce, 4);19601961/**1962* Version of the compose function that is more natural to read. Each function1963* consumes the return value of the previous function. It is the equivalent of1964* [compose]{@link module:ControlFlow.compose} with the arguments reversed.1965*1966* Each function is executed with the `this` binding of the composed function.1967*1968* @name seq1969* @static1970* @memberOf module:ControlFlow1971* @method1972* @see [async.compose]{@link module:ControlFlow.compose}1973* @category Control Flow1974* @param {...AsyncFunction} functions - the asynchronous functions to compose1975* @returns {Function} a function that composes the `functions` in order1976* @example1977*1978* // Requires lodash (or underscore), express3 and dresende's orm2.1979* // Part of an app, that fetches cats of the logged user.1980* // This example uses `seq` function to avoid overnesting and error1981* // handling clutter.1982* app.get('/cats', function(request, response) {1983* var User = request.models.User;1984* async.seq(1985* User.get.bind(User), // 'User.get' has signature (id, callback(err, data))1986* function(user, fn) {1987* user.getCats(fn); // 'getCats' has signature (callback(err, data))1988* }1989* )(req.session.user_id, function (err, cats) {1990* if (err) {1991* console.error(err);1992* response.json({ status: 'error', message: err.message });1993* } else {1994* response.json({ status: 'ok', message: 'Cats found', data: cats });1995* }1996* });1997* });1998*/1999function seq(...functions) {2000var _functions = functions.map(wrapAsync);2001return function (...args) {2002var that = this;20032004var cb = args[args.length - 1];2005if (typeof cb == 'function') {2006args.pop();2007} else {2008cb = promiseCallback();2009}20102011reduce$1(_functions, args, (newargs, fn, iterCb) => {2012fn.apply(that, newargs.concat((err, ...nextargs) => {2013iterCb(err, nextargs);2014}));2015},2016(err, results) => cb(err, ...results));20172018return cb[PROMISE_SYMBOL]2019};2020}20212022/**2023* Creates a function which is a composition of the passed asynchronous2024* functions. Each function consumes the return value of the function that2025* follows. Composing functions `f()`, `g()`, and `h()` would produce the result2026* of `f(g(h()))`, only this version uses callbacks to obtain the return values.2027*2028* If the last argument to the composed function is not a function, a promise2029* is returned when you call it.2030*2031* Each function is executed with the `this` binding of the composed function.2032*2033* @name compose2034* @static2035* @memberOf module:ControlFlow2036* @method2037* @category Control Flow2038* @param {...AsyncFunction} functions - the asynchronous functions to compose2039* @returns {Function} an asynchronous function that is the composed2040* asynchronous `functions`2041* @example2042*2043* function add1(n, callback) {2044* setTimeout(function () {2045* callback(null, n + 1);2046* }, 10);2047* }2048*2049* function mul3(n, callback) {2050* setTimeout(function () {2051* callback(null, n * 3);2052* }, 10);2053* }2054*2055* var add1mul3 = async.compose(mul3, add1);2056* add1mul3(4, function (err, result) {2057* // result now equals 152058* });2059*/2060function compose(...args) {2061return seq(...args.reverse());2062}20632064/**2065* The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.2066*2067* @name mapLimit2068* @static2069* @memberOf module:Collections2070* @method2071* @see [async.map]{@link module:Collections.map}2072* @category Collection2073* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2074* @param {number} limit - The maximum number of async operations at a time.2075* @param {AsyncFunction} iteratee - An async function to apply to each item in2076* `coll`.2077* The iteratee should complete with the transformed item.2078* Invoked with (item, callback).2079* @param {Function} [callback] - A callback which is called when all `iteratee`2080* functions have finished, or an error occurs. Results is an array of the2081* transformed items from the `coll`. Invoked with (err, results).2082* @returns {Promise} a promise, if no callback is passed2083*/2084function mapLimit (coll, limit, iteratee, callback) {2085return _asyncMap(eachOfLimit(limit), coll, iteratee, callback)2086}2087var mapLimit$1 = awaitify(mapLimit, 4);20882089/**2090* The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.2091*2092* @name concatLimit2093* @static2094* @memberOf module:Collections2095* @method2096* @see [async.concat]{@link module:Collections.concat}2097* @category Collection2098* @alias flatMapLimit2099* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2100* @param {number} limit - The maximum number of async operations at a time.2101* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,2102* which should use an array as its result. Invoked with (item, callback).2103* @param {Function} [callback] - A callback which is called after all the2104* `iteratee` functions have finished, or an error occurs. Results is an array2105* containing the concatenated results of the `iteratee` function. Invoked with2106* (err, results).2107* @returns A Promise, if no callback is passed2108*/2109function concatLimit(coll, limit, iteratee, callback) {2110var _iteratee = wrapAsync(iteratee);2111return mapLimit$1(coll, limit, (val, iterCb) => {2112_iteratee(val, (err, ...args) => {2113if (err) return iterCb(err);2114return iterCb(err, args);2115});2116}, (err, mapResults) => {2117var result = [];2118for (var i = 0; i < mapResults.length; i++) {2119if (mapResults[i]) {2120result = result.concat(...mapResults[i]);2121}2122}21232124return callback(err, result);2125});2126}2127var concatLimit$1 = awaitify(concatLimit, 4);21282129/**2130* Applies `iteratee` to each item in `coll`, concatenating the results. Returns2131* the concatenated list. The `iteratee`s are called in parallel, and the2132* results are concatenated as they return. The results array will be returned in2133* the original order of `coll` passed to the `iteratee` function.2134*2135* @name concat2136* @static2137* @memberOf module:Collections2138* @method2139* @category Collection2140* @alias flatMap2141* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2142* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,2143* which should use an array as its result. Invoked with (item, callback).2144* @param {Function} [callback] - A callback which is called after all the2145* `iteratee` functions have finished, or an error occurs. Results is an array2146* containing the concatenated results of the `iteratee` function. Invoked with2147* (err, results).2148* @returns A Promise, if no callback is passed2149* @example2150*2151* // dir1 is a directory that contains file1.txt, file2.txt2152* // dir2 is a directory that contains file3.txt, file4.txt2153* // dir3 is a directory that contains file5.txt2154* // dir4 does not exist2155*2156* let directoryList = ['dir1','dir2','dir3'];2157* let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];2158*2159* // Using callbacks2160* async.concat(directoryList, fs.readdir, function(err, results) {2161* if (err) {2162* console.log(err);2163* } else {2164* console.log(results);2165* // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]2166* }2167* });2168*2169* // Error Handling2170* async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {2171* if (err) {2172* console.log(err);2173* // [ Error: ENOENT: no such file or directory ]2174* // since dir4 does not exist2175* } else {2176* console.log(results);2177* }2178* });2179*2180* // Using Promises2181* async.concat(directoryList, fs.readdir)2182* .then(results => {2183* console.log(results);2184* // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]2185* }).catch(err => {2186* console.log(err);2187* });2188*2189* // Error Handling2190* async.concat(withMissingDirectoryList, fs.readdir)2191* .then(results => {2192* console.log(results);2193* }).catch(err => {2194* console.log(err);2195* // [ Error: ENOENT: no such file or directory ]2196* // since dir4 does not exist2197* });2198*2199* // Using async/await2200* async () => {2201* try {2202* let results = await async.concat(directoryList, fs.readdir);2203* console.log(results);2204* // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]2205* } catch (err) {2206* console.log(err);2207* }2208* }2209*2210* // Error Handling2211* async () => {2212* try {2213* let results = await async.concat(withMissingDirectoryList, fs.readdir);2214* console.log(results);2215* } catch (err) {2216* console.log(err);2217* // [ Error: ENOENT: no such file or directory ]2218* // since dir4 does not exist2219* }2220* }2221*2222*/2223function concat(coll, iteratee, callback) {2224return concatLimit$1(coll, Infinity, iteratee, callback)2225}2226var concat$1 = awaitify(concat, 3);22272228/**2229* The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.2230*2231* @name concatSeries2232* @static2233* @memberOf module:Collections2234* @method2235* @see [async.concat]{@link module:Collections.concat}2236* @category Collection2237* @alias flatMapSeries2238* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2239* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.2240* The iteratee should complete with an array an array of results.2241* Invoked with (item, callback).2242* @param {Function} [callback] - A callback which is called after all the2243* `iteratee` functions have finished, or an error occurs. Results is an array2244* containing the concatenated results of the `iteratee` function. Invoked with2245* (err, results).2246* @returns A Promise, if no callback is passed2247*/2248function concatSeries(coll, iteratee, callback) {2249return concatLimit$1(coll, 1, iteratee, callback)2250}2251var concatSeries$1 = awaitify(concatSeries, 3);22522253/**2254* Returns a function that when called, calls-back with the values provided.2255* Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to2256* [`auto`]{@link module:ControlFlow.auto}.2257*2258* @name constant2259* @static2260* @memberOf module:Utils2261* @method2262* @category Util2263* @param {...*} arguments... - Any number of arguments to automatically invoke2264* callback with.2265* @returns {AsyncFunction} Returns a function that when invoked, automatically2266* invokes the callback with the previous given arguments.2267* @example2268*2269* async.waterfall([2270* async.constant(42),2271* function (value, next) {2272* // value === 422273* },2274* //...2275* ], callback);2276*2277* async.waterfall([2278* async.constant(filename, "utf8"),2279* fs.readFile,2280* function (fileData, next) {2281* //...2282* }2283* //...2284* ], callback);2285*2286* async.auto({2287* hostname: async.constant("https://server.net/"),2288* port: findFreePort,2289* launchServer: ["hostname", "port", function (options, cb) {2290* startServer(options, cb);2291* }],2292* //...2293* }, callback);2294*/2295function constant(...args) {2296return function (...ignoredArgs/*, callback*/) {2297var callback = ignoredArgs.pop();2298return callback(null, ...args);2299};2300}23012302function _createTester(check, getResult) {2303return (eachfn, arr, _iteratee, cb) => {2304var testPassed = false;2305var testResult;2306const iteratee = wrapAsync(_iteratee);2307eachfn(arr, (value, _, callback) => {2308iteratee(value, (err, result) => {2309if (err || err === false) return callback(err);23102311if (check(result) && !testResult) {2312testPassed = true;2313testResult = getResult(true, value);2314return callback(null, breakLoop);2315}2316callback();2317});2318}, err => {2319if (err) return cb(err);2320cb(null, testPassed ? testResult : getResult(false));2321});2322};2323}23242325/**2326* Returns the first value in `coll` that passes an async truth test. The2327* `iteratee` is applied in parallel, meaning the first iteratee to return2328* `true` will fire the detect `callback` with that result. That means the2329* result might not be the first item in the original `coll` (in terms of order)2330* that passes the test.23312332* If order within the original `coll` is important, then look at2333* [`detectSeries`]{@link module:Collections.detectSeries}.2334*2335* @name detect2336* @static2337* @memberOf module:Collections2338* @method2339* @alias find2340* @category Collections2341* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2342* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.2343* The iteratee must complete with a boolean value as its result.2344* Invoked with (item, callback).2345* @param {Function} [callback] - A callback which is called as soon as any2346* iteratee returns `true`, or after all the `iteratee` functions have finished.2347* Result will be the first item in the array that passes the truth test2348* (iteratee) or the value `undefined` if none passed. Invoked with2349* (err, result).2350* @returns A Promise, if no callback is passed2351* @example2352*2353* // dir1 is a directory that contains file1.txt, file2.txt2354* // dir2 is a directory that contains file3.txt, file4.txt2355* // dir3 is a directory that contains file5.txt2356*2357* // asynchronous function that checks if a file exists2358* function fileExists(file, callback) {2359* fs.access(file, fs.constants.F_OK, (err) => {2360* callback(null, !err);2361* });2362* }2363*2364* async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,2365* function(err, result) {2366* console.log(result);2367* // dir1/file1.txt2368* // result now equals the first file in the list that exists2369* }2370*);2371*2372* // Using Promises2373* async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)2374* .then(result => {2375* console.log(result);2376* // dir1/file1.txt2377* // result now equals the first file in the list that exists2378* }).catch(err => {2379* console.log(err);2380* });2381*2382* // Using async/await2383* async () => {2384* try {2385* let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);2386* console.log(result);2387* // dir1/file1.txt2388* // result now equals the file in the list that exists2389* }2390* catch (err) {2391* console.log(err);2392* }2393* }2394*2395*/2396function detect(coll, iteratee, callback) {2397return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)2398}2399var detect$1 = awaitify(detect, 3);24002401/**2402* The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a2403* time.2404*2405* @name detectLimit2406* @static2407* @memberOf module:Collections2408* @method2409* @see [async.detect]{@link module:Collections.detect}2410* @alias findLimit2411* @category Collections2412* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2413* @param {number} limit - The maximum number of async operations at a time.2414* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.2415* The iteratee must complete with a boolean value as its result.2416* Invoked with (item, callback).2417* @param {Function} [callback] - A callback which is called as soon as any2418* iteratee returns `true`, or after all the `iteratee` functions have finished.2419* Result will be the first item in the array that passes the truth test2420* (iteratee) or the value `undefined` if none passed. Invoked with2421* (err, result).2422* @returns a Promise if no callback is passed2423*/2424function detectLimit(coll, limit, iteratee, callback) {2425return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback)2426}2427var detectLimit$1 = awaitify(detectLimit, 4);24282429/**2430* The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.2431*2432* @name detectSeries2433* @static2434* @memberOf module:Collections2435* @method2436* @see [async.detect]{@link module:Collections.detect}2437* @alias findSeries2438* @category Collections2439* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2440* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.2441* The iteratee must complete with a boolean value as its result.2442* Invoked with (item, callback).2443* @param {Function} [callback] - A callback which is called as soon as any2444* iteratee returns `true`, or after all the `iteratee` functions have finished.2445* Result will be the first item in the array that passes the truth test2446* (iteratee) or the value `undefined` if none passed. Invoked with2447* (err, result).2448* @returns a Promise if no callback is passed2449*/2450function detectSeries(coll, iteratee, callback) {2451return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback)2452}24532454var detectSeries$1 = awaitify(detectSeries, 3);24552456function consoleFunc(name) {2457return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {2458/* istanbul ignore else */2459if (typeof console === 'object') {2460/* istanbul ignore else */2461if (err) {2462/* istanbul ignore else */2463if (console.error) {2464console.error(err);2465}2466} else if (console[name]) { /* istanbul ignore else */2467resultArgs.forEach(x => console[name](x));2468}2469}2470})2471}24722473/**2474* Logs the result of an [`async` function]{@link AsyncFunction} to the2475* `console` using `console.dir` to display the properties of the resulting object.2476* Only works in Node.js or in browsers that support `console.dir` and2477* `console.error` (such as FF and Chrome).2478* If multiple arguments are returned from the async function,2479* `console.dir` is called on each argument in order.2480*2481* @name dir2482* @static2483* @memberOf module:Utils2484* @method2485* @category Util2486* @param {AsyncFunction} function - The function you want to eventually apply2487* all arguments to.2488* @param {...*} arguments... - Any number of arguments to apply to the function.2489* @example2490*2491* // in a module2492* var hello = function(name, callback) {2493* setTimeout(function() {2494* callback(null, {hello: name});2495* }, 1000);2496* };2497*2498* // in the node repl2499* node> async.dir(hello, 'world');2500* {hello: 'world'}2501*/2502var dir = consoleFunc('dir');25032504/**2505* The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in2506* the order of operations, the arguments `test` and `iteratee` are switched.2507*2508* `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.2509*2510* @name doWhilst2511* @static2512* @memberOf module:ControlFlow2513* @method2514* @see [async.whilst]{@link module:ControlFlow.whilst}2515* @category Control Flow2516* @param {AsyncFunction} iteratee - A function which is called each time `test`2517* passes. Invoked with (callback).2518* @param {AsyncFunction} test - asynchronous truth test to perform after each2519* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the2520* non-error args from the previous callback of `iteratee`.2521* @param {Function} [callback] - A callback which is called after the test2522* function has failed and repeated execution of `iteratee` has stopped.2523* `callback` will be passed an error and any arguments passed to the final2524* `iteratee`'s callback. Invoked with (err, [results]);2525* @returns {Promise} a promise, if no callback is passed2526*/2527function doWhilst(iteratee, test, callback) {2528callback = onlyOnce(callback);2529var _fn = wrapAsync(iteratee);2530var _test = wrapAsync(test);2531var results;25322533function next(err, ...args) {2534if (err) return callback(err);2535if (err === false) return;2536results = args;2537_test(...args, check);2538}25392540function check(err, truth) {2541if (err) return callback(err);2542if (err === false) return;2543if (!truth) return callback(null, ...results);2544_fn(next);2545}25462547return check(null, true);2548}25492550var doWhilst$1 = awaitify(doWhilst, 3);25512552/**2553* Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the2554* argument ordering differs from `until`.2555*2556* @name doUntil2557* @static2558* @memberOf module:ControlFlow2559* @method2560* @see [async.doWhilst]{@link module:ControlFlow.doWhilst}2561* @category Control Flow2562* @param {AsyncFunction} iteratee - An async function which is called each time2563* `test` fails. Invoked with (callback).2564* @param {AsyncFunction} test - asynchronous truth test to perform after each2565* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the2566* non-error args from the previous callback of `iteratee`2567* @param {Function} [callback] - A callback which is called after the test2568* function has passed and repeated execution of `iteratee` has stopped. `callback`2569* will be passed an error and any arguments passed to the final `iteratee`'s2570* callback. Invoked with (err, [results]);2571* @returns {Promise} a promise, if no callback is passed2572*/2573function doUntil(iteratee, test, callback) {2574const _test = wrapAsync(test);2575return doWhilst$1(iteratee, (...args) => {2576const cb = args.pop();2577_test(...args, (err, truth) => cb (err, !truth));2578}, callback);2579}25802581function _withoutIndex(iteratee) {2582return (value, index, callback) => iteratee(value, callback);2583}25842585/**2586* Applies the function `iteratee` to each item in `coll`, in parallel.2587* The `iteratee` is called with an item from the list, and a callback for when2588* it has finished. If the `iteratee` passes an error to its `callback`, the2589* main `callback` (for the `each` function) is immediately called with the2590* error.2591*2592* Note, that since this function applies `iteratee` to each item in parallel,2593* there is no guarantee that the iteratee functions will complete in order.2594*2595* @name each2596* @static2597* @memberOf module:Collections2598* @method2599* @alias forEach2600* @category Collection2601* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2602* @param {AsyncFunction} iteratee - An async function to apply to2603* each item in `coll`. Invoked with (item, callback).2604* The array index is not passed to the iteratee.2605* If you need the index, use `eachOf`.2606* @param {Function} [callback] - A callback which is called when all2607* `iteratee` functions have finished, or an error occurs. Invoked with (err).2608* @returns {Promise} a promise, if a callback is omitted2609* @example2610*2611* // dir1 is a directory that contains file1.txt, file2.txt2612* // dir2 is a directory that contains file3.txt, file4.txt2613* // dir3 is a directory that contains file5.txt2614* // dir4 does not exist2615*2616* const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];2617* const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];2618*2619* // asynchronous function that deletes a file2620* const deleteFile = function(file, callback) {2621* fs.unlink(file, callback);2622* };2623*2624* // Using callbacks2625* async.each(fileList, deleteFile, function(err) {2626* if( err ) {2627* console.log(err);2628* } else {2629* console.log('All files have been deleted successfully');2630* }2631* });2632*2633* // Error Handling2634* async.each(withMissingFileList, deleteFile, function(err){2635* console.log(err);2636* // [ Error: ENOENT: no such file or directory ]2637* // since dir4/file2.txt does not exist2638* // dir1/file1.txt could have been deleted2639* });2640*2641* // Using Promises2642* async.each(fileList, deleteFile)2643* .then( () => {2644* console.log('All files have been deleted successfully');2645* }).catch( err => {2646* console.log(err);2647* });2648*2649* // Error Handling2650* async.each(fileList, deleteFile)2651* .then( () => {2652* console.log('All files have been deleted successfully');2653* }).catch( err => {2654* console.log(err);2655* // [ Error: ENOENT: no such file or directory ]2656* // since dir4/file2.txt does not exist2657* // dir1/file1.txt could have been deleted2658* });2659*2660* // Using async/await2661* async () => {2662* try {2663* await async.each(files, deleteFile);2664* }2665* catch (err) {2666* console.log(err);2667* }2668* }2669*2670* // Error Handling2671* async () => {2672* try {2673* await async.each(withMissingFileList, deleteFile);2674* }2675* catch (err) {2676* console.log(err);2677* // [ Error: ENOENT: no such file or directory ]2678* // since dir4/file2.txt does not exist2679* // dir1/file1.txt could have been deleted2680* }2681* }2682*2683*/2684function eachLimit(coll, iteratee, callback) {2685return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);2686}26872688var each = awaitify(eachLimit, 3);26892690/**2691* The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.2692*2693* @name eachLimit2694* @static2695* @memberOf module:Collections2696* @method2697* @see [async.each]{@link module:Collections.each}2698* @alias forEachLimit2699* @category Collection2700* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2701* @param {number} limit - The maximum number of async operations at a time.2702* @param {AsyncFunction} iteratee - An async function to apply to each item in2703* `coll`.2704* The array index is not passed to the iteratee.2705* If you need the index, use `eachOfLimit`.2706* Invoked with (item, callback).2707* @param {Function} [callback] - A callback which is called when all2708* `iteratee` functions have finished, or an error occurs. Invoked with (err).2709* @returns {Promise} a promise, if a callback is omitted2710*/2711function eachLimit$1(coll, limit, iteratee, callback) {2712return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);2713}2714var eachLimit$2 = awaitify(eachLimit$1, 4);27152716/**2717* The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.2718*2719* Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item2720* in series and therefore the iteratee functions will complete in order.27212722* @name eachSeries2723* @static2724* @memberOf module:Collections2725* @method2726* @see [async.each]{@link module:Collections.each}2727* @alias forEachSeries2728* @category Collection2729* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2730* @param {AsyncFunction} iteratee - An async function to apply to each2731* item in `coll`.2732* The array index is not passed to the iteratee.2733* If you need the index, use `eachOfSeries`.2734* Invoked with (item, callback).2735* @param {Function} [callback] - A callback which is called when all2736* `iteratee` functions have finished, or an error occurs. Invoked with (err).2737* @returns {Promise} a promise, if a callback is omitted2738*/2739function eachSeries(coll, iteratee, callback) {2740return eachLimit$2(coll, 1, iteratee, callback)2741}2742var eachSeries$1 = awaitify(eachSeries, 3);27432744/**2745* Wrap an async function and ensure it calls its callback on a later tick of2746* the event loop. If the function already calls its callback on a next tick,2747* no extra deferral is added. This is useful for preventing stack overflows2748* (`RangeError: Maximum call stack size exceeded`) and generally keeping2749* [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)2750* contained. ES2017 `async` functions are returned as-is -- they are immune2751* to Zalgo's corrupting influences, as they always resolve on a later tick.2752*2753* @name ensureAsync2754* @static2755* @memberOf module:Utils2756* @method2757* @category Util2758* @param {AsyncFunction} fn - an async function, one that expects a node-style2759* callback as its last argument.2760* @returns {AsyncFunction} Returns a wrapped function with the exact same call2761* signature as the function passed in.2762* @example2763*2764* function sometimesAsync(arg, callback) {2765* if (cache[arg]) {2766* return callback(null, cache[arg]); // this would be synchronous!!2767* } else {2768* doSomeIO(arg, callback); // this IO would be asynchronous2769* }2770* }2771*2772* // this has a risk of stack overflows if many results are cached in a row2773* async.mapSeries(args, sometimesAsync, done);2774*2775* // this will defer sometimesAsync's callback if necessary,2776* // preventing stack overflows2777* async.mapSeries(args, async.ensureAsync(sometimesAsync), done);2778*/2779function ensureAsync(fn) {2780if (isAsync(fn)) return fn;2781return function (...args/*, callback*/) {2782var callback = args.pop();2783var sync = true;2784args.push((...innerArgs) => {2785if (sync) {2786setImmediate$1(() => callback(...innerArgs));2787} else {2788callback(...innerArgs);2789}2790});2791fn.apply(this, args);2792sync = false;2793};2794}27952796/**2797* Returns `true` if every element in `coll` satisfies an async test. If any2798* iteratee call returns `false`, the main `callback` is immediately called.2799*2800* @name every2801* @static2802* @memberOf module:Collections2803* @method2804* @alias all2805* @category Collection2806* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2807* @param {AsyncFunction} iteratee - An async truth test to apply to each item2808* in the collection in parallel.2809* The iteratee must complete with a boolean result value.2810* Invoked with (item, callback).2811* @param {Function} [callback] - A callback which is called after all the2812* `iteratee` functions have finished. Result will be either `true` or `false`2813* depending on the values of the async tests. Invoked with (err, result).2814* @returns {Promise} a promise, if no callback provided2815* @example2816*2817* // dir1 is a directory that contains file1.txt, file2.txt2818* // dir2 is a directory that contains file3.txt, file4.txt2819* // dir3 is a directory that contains file5.txt2820* // dir4 does not exist2821*2822* const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];2823* const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];2824*2825* // asynchronous function that checks if a file exists2826* function fileExists(file, callback) {2827* fs.access(file, fs.constants.F_OK, (err) => {2828* callback(null, !err);2829* });2830* }2831*2832* // Using callbacks2833* async.every(fileList, fileExists, function(err, result) {2834* console.log(result);2835* // true2836* // result is true since every file exists2837* });2838*2839* async.every(withMissingFileList, fileExists, function(err, result) {2840* console.log(result);2841* // false2842* // result is false since NOT every file exists2843* });2844*2845* // Using Promises2846* async.every(fileList, fileExists)2847* .then( result => {2848* console.log(result);2849* // true2850* // result is true since every file exists2851* }).catch( err => {2852* console.log(err);2853* });2854*2855* async.every(withMissingFileList, fileExists)2856* .then( result => {2857* console.log(result);2858* // false2859* // result is false since NOT every file exists2860* }).catch( err => {2861* console.log(err);2862* });2863*2864* // Using async/await2865* async () => {2866* try {2867* let result = await async.every(fileList, fileExists);2868* console.log(result);2869* // true2870* // result is true since every file exists2871* }2872* catch (err) {2873* console.log(err);2874* }2875* }2876*2877* async () => {2878* try {2879* let result = await async.every(withMissingFileList, fileExists);2880* console.log(result);2881* // false2882* // result is false since NOT every file exists2883* }2884* catch (err) {2885* console.log(err);2886* }2887* }2888*2889*/2890function every(coll, iteratee, callback) {2891return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)2892}2893var every$1 = awaitify(every, 3);28942895/**2896* The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.2897*2898* @name everyLimit2899* @static2900* @memberOf module:Collections2901* @method2902* @see [async.every]{@link module:Collections.every}2903* @alias allLimit2904* @category Collection2905* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2906* @param {number} limit - The maximum number of async operations at a time.2907* @param {AsyncFunction} iteratee - An async truth test to apply to each item2908* in the collection in parallel.2909* The iteratee must complete with a boolean result value.2910* Invoked with (item, callback).2911* @param {Function} [callback] - A callback which is called after all the2912* `iteratee` functions have finished. Result will be either `true` or `false`2913* depending on the values of the async tests. Invoked with (err, result).2914* @returns {Promise} a promise, if no callback provided2915*/2916function everyLimit(coll, limit, iteratee, callback) {2917return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback)2918}2919var everyLimit$1 = awaitify(everyLimit, 4);29202921/**2922* The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.2923*2924* @name everySeries2925* @static2926* @memberOf module:Collections2927* @method2928* @see [async.every]{@link module:Collections.every}2929* @alias allSeries2930* @category Collection2931* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2932* @param {AsyncFunction} iteratee - An async truth test to apply to each item2933* in the collection in series.2934* The iteratee must complete with a boolean result value.2935* Invoked with (item, callback).2936* @param {Function} [callback] - A callback which is called after all the2937* `iteratee` functions have finished. Result will be either `true` or `false`2938* depending on the values of the async tests. Invoked with (err, result).2939* @returns {Promise} a promise, if no callback provided2940*/2941function everySeries(coll, iteratee, callback) {2942return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)2943}2944var everySeries$1 = awaitify(everySeries, 3);29452946function filterArray(eachfn, arr, iteratee, callback) {2947var truthValues = new Array(arr.length);2948eachfn(arr, (x, index, iterCb) => {2949iteratee(x, (err, v) => {2950truthValues[index] = !!v;2951iterCb(err);2952});2953}, err => {2954if (err) return callback(err);2955var results = [];2956for (var i = 0; i < arr.length; i++) {2957if (truthValues[i]) results.push(arr[i]);2958}2959callback(null, results);2960});2961}29622963function filterGeneric(eachfn, coll, iteratee, callback) {2964var results = [];2965eachfn(coll, (x, index, iterCb) => {2966iteratee(x, (err, v) => {2967if (err) return iterCb(err);2968if (v) {2969results.push({index, value: x});2970}2971iterCb(err);2972});2973}, err => {2974if (err) return callback(err);2975callback(null, results2976.sort((a, b) => a.index - b.index)2977.map(v => v.value));2978});2979}29802981function _filter(eachfn, coll, iteratee, callback) {2982var filter = isArrayLike(coll) ? filterArray : filterGeneric;2983return filter(eachfn, coll, wrapAsync(iteratee), callback);2984}29852986/**2987* Returns a new array of all the values in `coll` which pass an async truth2988* test. This operation is performed in parallel, but the results array will be2989* in the same order as the original.2990*2991* @name filter2992* @static2993* @memberOf module:Collections2994* @method2995* @alias select2996* @category Collection2997* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.2998* @param {Function} iteratee - A truth test to apply to each item in `coll`.2999* The `iteratee` is passed a `callback(err, truthValue)`, which must be called3000* with a boolean argument once it has completed. Invoked with (item, callback).3001* @param {Function} [callback] - A callback which is called after all the3002* `iteratee` functions have finished. Invoked with (err, results).3003* @returns {Promise} a promise, if no callback provided3004* @example3005*3006* // dir1 is a directory that contains file1.txt, file2.txt3007* // dir2 is a directory that contains file3.txt, file4.txt3008* // dir3 is a directory that contains file5.txt3009*3010* const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];3011*3012* // asynchronous function that checks if a file exists3013* function fileExists(file, callback) {3014* fs.access(file, fs.constants.F_OK, (err) => {3015* callback(null, !err);3016* });3017* }3018*3019* // Using callbacks3020* async.filter(files, fileExists, function(err, results) {3021* if(err) {3022* console.log(err);3023* } else {3024* console.log(results);3025* // [ 'dir1/file1.txt', 'dir2/file3.txt' ]3026* // results is now an array of the existing files3027* }3028* });3029*3030* // Using Promises3031* async.filter(files, fileExists)3032* .then(results => {3033* console.log(results);3034* // [ 'dir1/file1.txt', 'dir2/file3.txt' ]3035* // results is now an array of the existing files3036* }).catch(err => {3037* console.log(err);3038* });3039*3040* // Using async/await3041* async () => {3042* try {3043* let results = await async.filter(files, fileExists);3044* console.log(results);3045* // [ 'dir1/file1.txt', 'dir2/file3.txt' ]3046* // results is now an array of the existing files3047* }3048* catch (err) {3049* console.log(err);3050* }3051* }3052*3053*/3054function filter (coll, iteratee, callback) {3055return _filter(eachOf$1, coll, iteratee, callback)3056}3057var filter$1 = awaitify(filter, 3);30583059/**3060* The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a3061* time.3062*3063* @name filterLimit3064* @static3065* @memberOf module:Collections3066* @method3067* @see [async.filter]{@link module:Collections.filter}3068* @alias selectLimit3069* @category Collection3070* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3071* @param {number} limit - The maximum number of async operations at a time.3072* @param {Function} iteratee - A truth test to apply to each item in `coll`.3073* The `iteratee` is passed a `callback(err, truthValue)`, which must be called3074* with a boolean argument once it has completed. Invoked with (item, callback).3075* @param {Function} [callback] - A callback which is called after all the3076* `iteratee` functions have finished. Invoked with (err, results).3077* @returns {Promise} a promise, if no callback provided3078*/3079function filterLimit (coll, limit, iteratee, callback) {3080return _filter(eachOfLimit(limit), coll, iteratee, callback)3081}3082var filterLimit$1 = awaitify(filterLimit, 4);30833084/**3085* The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.3086*3087* @name filterSeries3088* @static3089* @memberOf module:Collections3090* @method3091* @see [async.filter]{@link module:Collections.filter}3092* @alias selectSeries3093* @category Collection3094* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3095* @param {Function} iteratee - A truth test to apply to each item in `coll`.3096* The `iteratee` is passed a `callback(err, truthValue)`, which must be called3097* with a boolean argument once it has completed. Invoked with (item, callback).3098* @param {Function} [callback] - A callback which is called after all the3099* `iteratee` functions have finished. Invoked with (err, results)3100* @returns {Promise} a promise, if no callback provided3101*/3102function filterSeries (coll, iteratee, callback) {3103return _filter(eachOfSeries$1, coll, iteratee, callback)3104}3105var filterSeries$1 = awaitify(filterSeries, 3);31063107/**3108* Calls the asynchronous function `fn` with a callback parameter that allows it3109* to call itself again, in series, indefinitely.31103111* If an error is passed to the callback then `errback` is called with the3112* error, and execution stops, otherwise it will never be called.3113*3114* @name forever3115* @static3116* @memberOf module:ControlFlow3117* @method3118* @category Control Flow3119* @param {AsyncFunction} fn - an async function to call repeatedly.3120* Invoked with (next).3121* @param {Function} [errback] - when `fn` passes an error to it's callback,3122* this function will be called, and execution stops. Invoked with (err).3123* @returns {Promise} a promise that rejects if an error occurs and an errback3124* is not passed3125* @example3126*3127* async.forever(3128* function(next) {3129* // next is suitable for passing to things that need a callback(err [, whatever]);3130* // it will result in this function being called again.3131* },3132* function(err) {3133* // if next is called with a value in its first parameter, it will appear3134* // in here as 'err', and execution will stop.3135* }3136* );3137*/3138function forever(fn, errback) {3139var done = onlyOnce(errback);3140var task = wrapAsync(ensureAsync(fn));31413142function next(err) {3143if (err) return done(err);3144if (err === false) return;3145task(next);3146}3147return next();3148}3149var forever$1 = awaitify(forever, 2);31503151/**3152* The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.3153*3154* @name groupByLimit3155* @static3156* @memberOf module:Collections3157* @method3158* @see [async.groupBy]{@link module:Collections.groupBy}3159* @category Collection3160* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3161* @param {number} limit - The maximum number of async operations at a time.3162* @param {AsyncFunction} iteratee - An async function to apply to each item in3163* `coll`.3164* The iteratee should complete with a `key` to group the value under.3165* Invoked with (value, callback).3166* @param {Function} [callback] - A callback which is called when all `iteratee`3167* functions have finished, or an error occurs. Result is an `Object` whoses3168* properties are arrays of values which returned the corresponding key.3169* @returns {Promise} a promise, if no callback is passed3170*/3171function groupByLimit(coll, limit, iteratee, callback) {3172var _iteratee = wrapAsync(iteratee);3173return mapLimit$1(coll, limit, (val, iterCb) => {3174_iteratee(val, (err, key) => {3175if (err) return iterCb(err);3176return iterCb(err, {key, val});3177});3178}, (err, mapResults) => {3179var result = {};3180// from MDN, handle object having an `hasOwnProperty` prop3181var {hasOwnProperty} = Object.prototype;31823183for (var i = 0; i < mapResults.length; i++) {3184if (mapResults[i]) {3185var {key} = mapResults[i];3186var {val} = mapResults[i];31873188if (hasOwnProperty.call(result, key)) {3189result[key].push(val);3190} else {3191result[key] = [val];3192}3193}3194}31953196return callback(err, result);3197});3198}31993200var groupByLimit$1 = awaitify(groupByLimit, 4);32013202/**3203* Returns a new object, where each value corresponds to an array of items, from3204* `coll`, that returned the corresponding key. That is, the keys of the object3205* correspond to the values passed to the `iteratee` callback.3206*3207* Note: Since this function applies the `iteratee` to each item in parallel,3208* there is no guarantee that the `iteratee` functions will complete in order.3209* However, the values for each key in the `result` will be in the same order as3210* the original `coll`. For Objects, the values will roughly be in the order of3211* the original Objects' keys (but this can vary across JavaScript engines).3212*3213* @name groupBy3214* @static3215* @memberOf module:Collections3216* @method3217* @category Collection3218* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3219* @param {AsyncFunction} iteratee - An async function to apply to each item in3220* `coll`.3221* The iteratee should complete with a `key` to group the value under.3222* Invoked with (value, callback).3223* @param {Function} [callback] - A callback which is called when all `iteratee`3224* functions have finished, or an error occurs. Result is an `Object` whoses3225* properties are arrays of values which returned the corresponding key.3226* @returns {Promise} a promise, if no callback is passed3227* @example3228*3229* // dir1 is a directory that contains file1.txt, file2.txt3230* // dir2 is a directory that contains file3.txt, file4.txt3231* // dir3 is a directory that contains file5.txt3232* // dir4 does not exist3233*3234* const files = ['dir1/file1.txt','dir2','dir4']3235*3236* // asynchronous function that detects file type as none, file, or directory3237* function detectFile(file, callback) {3238* fs.stat(file, function(err, stat) {3239* if (err) {3240* return callback(null, 'none');3241* }3242* callback(null, stat.isDirectory() ? 'directory' : 'file');3243* });3244* }3245*3246* //Using callbacks3247* async.groupBy(files, detectFile, function(err, result) {3248* if(err) {3249* console.log(err);3250* } else {3251* console.log(result);3252* // {3253* // file: [ 'dir1/file1.txt' ],3254* // none: [ 'dir4' ],3255* // directory: [ 'dir2']3256* // }3257* // result is object containing the files grouped by type3258* }3259* });3260*3261* // Using Promises3262* async.groupBy(files, detectFile)3263* .then( result => {3264* console.log(result);3265* // {3266* // file: [ 'dir1/file1.txt' ],3267* // none: [ 'dir4' ],3268* // directory: [ 'dir2']3269* // }3270* // result is object containing the files grouped by type3271* }).catch( err => {3272* console.log(err);3273* });3274*3275* // Using async/await3276* async () => {3277* try {3278* let result = await async.groupBy(files, detectFile);3279* console.log(result);3280* // {3281* // file: [ 'dir1/file1.txt' ],3282* // none: [ 'dir4' ],3283* // directory: [ 'dir2']3284* // }3285* // result is object containing the files grouped by type3286* }3287* catch (err) {3288* console.log(err);3289* }3290* }3291*3292*/3293function groupBy (coll, iteratee, callback) {3294return groupByLimit$1(coll, Infinity, iteratee, callback)3295}32963297/**3298* The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.3299*3300* @name groupBySeries3301* @static3302* @memberOf module:Collections3303* @method3304* @see [async.groupBy]{@link module:Collections.groupBy}3305* @category Collection3306* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.3307* @param {AsyncFunction} iteratee - An async function to apply to each item in3308* `coll`.3309* The iteratee should complete with a `key` to group the value under.3310* Invoked with (value, callback).3311* @param {Function} [callback] - A callback which is called when all `iteratee`3312* functions have finished, or an error occurs. Result is an `Object` whose3313* properties are arrays of values which returned the corresponding key.3314* @returns {Promise} a promise, if no callback is passed3315*/3316function groupBySeries (coll, iteratee, callback) {3317return groupByLimit$1(coll, 1, iteratee, callback)3318}33193320/**3321* Logs the result of an `async` function to the `console`. Only works in3322* Node.js or in browsers that support `console.log` and `console.error` (such3323* as FF and Chrome). If multiple arguments are returned from the async3324* function, `console.log` is called on each argument in order.3325*3326* @name log3327* @static3328* @memberOf module:Utils3329* @method3330* @category Util3331* @param {AsyncFunction} function - The function you want to eventually apply3332* all arguments to.3333* @param {...*} arguments... - Any number of arguments to apply to the function.3334* @example3335*3336* // in a module3337* var hello = function(name, callback) {3338* setTimeout(function() {3339* callback(null, 'hello ' + name);3340* }, 1000);3341* };3342*3343* // in the node repl3344* node> async.log(hello, 'world');3345* 'hello world'3346*/3347var log = consoleFunc('log');33483349/**3350* The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a3351* time.3352*3353* @name mapValuesLimit3354* @static3355* @memberOf module:Collections3356* @method3357* @see [async.mapValues]{@link module:Collections.mapValues}3358* @category Collection3359* @param {Object} obj - A collection to iterate over.3360* @param {number} limit - The maximum number of async operations at a time.3361* @param {AsyncFunction} iteratee - A function to apply to each value and key3362* in `coll`.3363* The iteratee should complete with the transformed value as its result.3364* Invoked with (value, key, callback).3365* @param {Function} [callback] - A callback which is called when all `iteratee`3366* functions have finished, or an error occurs. `result` is a new object consisting3367* of each key from `obj`, with each transformed value on the right-hand side.3368* Invoked with (err, result).3369* @returns {Promise} a promise, if no callback is passed3370*/3371function mapValuesLimit(obj, limit, iteratee, callback) {3372callback = once(callback);3373var newObj = {};3374var _iteratee = wrapAsync(iteratee);3375return eachOfLimit(limit)(obj, (val, key, next) => {3376_iteratee(val, key, (err, result) => {3377if (err) return next(err);3378newObj[key] = result;3379next(err);3380});3381}, err => callback(err, newObj));3382}33833384var mapValuesLimit$1 = awaitify(mapValuesLimit, 4);33853386/**3387* A relative of [`map`]{@link module:Collections.map}, designed for use with objects.3388*3389* Produces a new Object by mapping each value of `obj` through the `iteratee`3390* function. The `iteratee` is called each `value` and `key` from `obj` and a3391* callback for when it has finished processing. Each of these callbacks takes3392* two arguments: an `error`, and the transformed item from `obj`. If `iteratee`3393* passes an error to its callback, the main `callback` (for the `mapValues`3394* function) is immediately called with the error.3395*3396* Note, the order of the keys in the result is not guaranteed. The keys will3397* be roughly in the order they complete, (but this is very engine-specific)3398*3399* @name mapValues3400* @static3401* @memberOf module:Collections3402* @method3403* @category Collection3404* @param {Object} obj - A collection to iterate over.3405* @param {AsyncFunction} iteratee - A function to apply to each value and key3406* in `coll`.3407* The iteratee should complete with the transformed value as its result.3408* Invoked with (value, key, callback).3409* @param {Function} [callback] - A callback which is called when all `iteratee`3410* functions have finished, or an error occurs. `result` is a new object consisting3411* of each key from `obj`, with each transformed value on the right-hand side.3412* Invoked with (err, result).3413* @returns {Promise} a promise, if no callback is passed3414* @example3415*3416* // file1.txt is a file that is 1000 bytes in size3417* // file2.txt is a file that is 2000 bytes in size3418* // file3.txt is a file that is 3000 bytes in size3419* // file4.txt does not exist3420*3421* const fileMap = {3422* f1: 'file1.txt',3423* f2: 'file2.txt',3424* f3: 'file3.txt'3425* };3426*3427* const withMissingFileMap = {3428* f1: 'file1.txt',3429* f2: 'file2.txt',3430* f3: 'file4.txt'3431* };3432*3433* // asynchronous function that returns the file size in bytes3434* function getFileSizeInBytes(file, key, callback) {3435* fs.stat(file, function(err, stat) {3436* if (err) {3437* return callback(err);3438* }3439* callback(null, stat.size);3440* });3441* }3442*3443* // Using callbacks3444* async.mapValues(fileMap, getFileSizeInBytes, function(err, result) {3445* if (err) {3446* console.log(err);3447* } else {3448* console.log(result);3449* // result is now a map of file size in bytes for each file, e.g.3450* // {3451* // f1: 1000,3452* // f2: 2000,3453* // f3: 30003454* // }3455* }3456* });3457*3458* // Error handling3459* async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) {3460* if (err) {3461* console.log(err);3462* // [ Error: ENOENT: no such file or directory ]3463* } else {3464* console.log(result);3465* }3466* });3467*3468* // Using Promises3469* async.mapValues(fileMap, getFileSizeInBytes)3470* .then( result => {3471* console.log(result);3472* // result is now a map of file size in bytes for each file, e.g.3473* // {3474* // f1: 1000,3475* // f2: 2000,3476* // f3: 30003477* // }3478* }).catch (err => {3479* console.log(err);3480* });3481*3482* // Error Handling3483* async.mapValues(withMissingFileMap, getFileSizeInBytes)3484* .then( result => {3485* console.log(result);3486* }).catch (err => {3487* console.log(err);3488* // [ Error: ENOENT: no such file or directory ]3489* });3490*3491* // Using async/await3492* async () => {3493* try {3494* let result = await async.mapValues(fileMap, getFileSizeInBytes);3495* console.log(result);3496* // result is now a map of file size in bytes for each file, e.g.3497* // {3498* // f1: 1000,3499* // f2: 2000,3500* // f3: 30003501* // }3502* }3503* catch (err) {3504* console.log(err);3505* }3506* }3507*3508* // Error Handling3509* async () => {3510* try {3511* let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes);3512* console.log(result);3513* }3514* catch (err) {3515* console.log(err);3516* // [ Error: ENOENT: no such file or directory ]3517* }3518* }3519*3520*/3521function mapValues(obj, iteratee, callback) {3522return mapValuesLimit$1(obj, Infinity, iteratee, callback)3523}35243525/**3526* The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.3527*3528* @name mapValuesSeries3529* @static3530* @memberOf module:Collections3531* @method3532* @see [async.mapValues]{@link module:Collections.mapValues}3533* @category Collection3534* @param {Object} obj - A collection to iterate over.3535* @param {AsyncFunction} iteratee - A function to apply to each value and key3536* in `coll`.3537* The iteratee should complete with the transformed value as its result.3538* Invoked with (value, key, callback).3539* @param {Function} [callback] - A callback which is called when all `iteratee`3540* functions have finished, or an error occurs. `result` is a new object consisting3541* of each key from `obj`, with each transformed value on the right-hand side.3542* Invoked with (err, result).3543* @returns {Promise} a promise, if no callback is passed3544*/3545function mapValuesSeries(obj, iteratee, callback) {3546return mapValuesLimit$1(obj, 1, iteratee, callback)3547}35483549/**3550* Caches the results of an async function. When creating a hash to store3551* function results against, the callback is omitted from the hash and an3552* optional hash function can be used.3553*3554* **Note: if the async function errs, the result will not be cached and3555* subsequent calls will call the wrapped function.**3556*3557* If no hash function is specified, the first argument is used as a hash key,3558* which may work reasonably if it is a string or a data type that converts to a3559* distinct string. Note that objects and arrays will not behave reasonably.3560* Neither will cases where the other arguments are significant. In such cases,3561* specify your own hash function.3562*3563* The cache of results is exposed as the `memo` property of the function3564* returned by `memoize`.3565*3566* @name memoize3567* @static3568* @memberOf module:Utils3569* @method3570* @category Util3571* @param {AsyncFunction} fn - The async function to proxy and cache results from.3572* @param {Function} hasher - An optional function for generating a custom hash3573* for storing results. It has all the arguments applied to it apart from the3574* callback, and must be synchronous.3575* @returns {AsyncFunction} a memoized version of `fn`3576* @example3577*3578* var slow_fn = function(name, callback) {3579* // do something3580* callback(null, result);3581* };3582* var fn = async.memoize(slow_fn);3583*3584* // fn can now be used as if it were slow_fn3585* fn('some name', function() {3586* // callback3587* });3588*/3589function memoize(fn, hasher = v => v) {3590var memo = Object.create(null);3591var queues = Object.create(null);3592var _fn = wrapAsync(fn);3593var memoized = initialParams((args, callback) => {3594var key = hasher(...args);3595if (key in memo) {3596setImmediate$1(() => callback(null, ...memo[key]));3597} else if (key in queues) {3598queues[key].push(callback);3599} else {3600queues[key] = [callback];3601_fn(...args, (err, ...resultArgs) => {3602// #1465 don't memoize if an error occurred3603if (!err) {3604memo[key] = resultArgs;3605}3606var q = queues[key];3607delete queues[key];3608for (var i = 0, l = q.length; i < l; i++) {3609q[i](err, ...resultArgs);3610}3611});3612}3613});3614memoized.memo = memo;3615memoized.unmemoized = fn;3616return memoized;3617}36183619/* istanbul ignore file */36203621/**3622* Calls `callback` on a later loop around the event loop. In Node.js this just3623* calls `process.nextTick`. In the browser it will use `setImmediate` if3624* available, otherwise `setTimeout(callback, 0)`, which means other higher3625* priority events may precede the execution of `callback`.3626*3627* This is used internally for browser-compatibility purposes.3628*3629* @name nextTick3630* @static3631* @memberOf module:Utils3632* @method3633* @see [async.setImmediate]{@link module:Utils.setImmediate}3634* @category Util3635* @param {Function} callback - The function to call on a later loop around3636* the event loop. Invoked with (args...).3637* @param {...*} args... - any number of additional arguments to pass to the3638* callback on the next tick.3639* @example3640*3641* var call_order = [];3642* async.nextTick(function() {3643* call_order.push('two');3644* // call_order now equals ['one','two']3645* });3646* call_order.push('one');3647*3648* async.setImmediate(function (a, b, c) {3649* // a, b, and c equal 1, 2, and 33650* }, 1, 2, 3);3651*/3652var _defer$1;36533654if (hasNextTick) {3655_defer$1 = process.nextTick;3656} else if (hasSetImmediate) {3657_defer$1 = setImmediate;3658} else {3659_defer$1 = fallback;3660}36613662var nextTick = wrap(_defer$1);36633664var _parallel = awaitify((eachfn, tasks, callback) => {3665var results = isArrayLike(tasks) ? [] : {};36663667eachfn(tasks, (task, key, taskCb) => {3668wrapAsync(task)((err, ...result) => {3669if (result.length < 2) {3670[result] = result;3671}3672results[key] = result;3673taskCb(err);3674});3675}, err => callback(err, results));3676}, 3);36773678/**3679* Run the `tasks` collection of functions in parallel, without waiting until3680* the previous function has completed. If any of the functions pass an error to3681* its callback, the main `callback` is immediately called with the value of the3682* error. Once the `tasks` have completed, the results are passed to the final3683* `callback` as an array.3684*3685* **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about3686* parallel execution of code. If your tasks do not use any timers or perform3687* any I/O, they will actually be executed in series. Any synchronous setup3688* sections for each task will happen one after the other. JavaScript remains3689* single-threaded.3690*3691* **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the3692* execution of other tasks when a task fails.3693*3694* It is also possible to use an object instead of an array. Each property will3695* be run as a function and the results will be passed to the final `callback`3696* as an object instead of an array. This can be a more readable way of handling3697* results from {@link async.parallel}.3698*3699* @name parallel3700* @static3701* @memberOf module:ControlFlow3702* @method3703* @category Control Flow3704* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of3705* [async functions]{@link AsyncFunction} to run.3706* Each async function can complete with any number of optional `result` values.3707* @param {Function} [callback] - An optional callback to run once all the3708* functions have completed successfully. This function gets a results array3709* (or object) containing all the result arguments passed to the task callbacks.3710* Invoked with (err, results).3711* @returns {Promise} a promise, if a callback is not passed3712*3713* @example3714*3715* //Using Callbacks3716* async.parallel([3717* function(callback) {3718* setTimeout(function() {3719* callback(null, 'one');3720* }, 200);3721* },3722* function(callback) {3723* setTimeout(function() {3724* callback(null, 'two');3725* }, 100);3726* }3727* ], function(err, results) {3728* console.log(results);3729* // results is equal to ['one','two'] even though3730* // the second function had a shorter timeout.3731* });3732*3733* // an example using an object instead of an array3734* async.parallel({3735* one: function(callback) {3736* setTimeout(function() {3737* callback(null, 1);3738* }, 200);3739* },3740* two: function(callback) {3741* setTimeout(function() {3742* callback(null, 2);3743* }, 100);3744* }3745* }, function(err, results) {3746* console.log(results);3747* // results is equal to: { one: 1, two: 2 }3748* });3749*3750* //Using Promises3751* async.parallel([3752* function(callback) {3753* setTimeout(function() {3754* callback(null, 'one');3755* }, 200);3756* },3757* function(callback) {3758* setTimeout(function() {3759* callback(null, 'two');3760* }, 100);3761* }3762* ]).then(results => {3763* console.log(results);3764* // results is equal to ['one','two'] even though3765* // the second function had a shorter timeout.3766* }).catch(err => {3767* console.log(err);3768* });3769*3770* // an example using an object instead of an array3771* async.parallel({3772* one: function(callback) {3773* setTimeout(function() {3774* callback(null, 1);3775* }, 200);3776* },3777* two: function(callback) {3778* setTimeout(function() {3779* callback(null, 2);3780* }, 100);3781* }3782* }).then(results => {3783* console.log(results);3784* // results is equal to: { one: 1, two: 2 }3785* }).catch(err => {3786* console.log(err);3787* });3788*3789* //Using async/await3790* async () => {3791* try {3792* let results = await async.parallel([3793* function(callback) {3794* setTimeout(function() {3795* callback(null, 'one');3796* }, 200);3797* },3798* function(callback) {3799* setTimeout(function() {3800* callback(null, 'two');3801* }, 100);3802* }3803* ]);3804* console.log(results);3805* // results is equal to ['one','two'] even though3806* // the second function had a shorter timeout.3807* }3808* catch (err) {3809* console.log(err);3810* }3811* }3812*3813* // an example using an object instead of an array3814* async () => {3815* try {3816* let results = await async.parallel({3817* one: function(callback) {3818* setTimeout(function() {3819* callback(null, 1);3820* }, 200);3821* },3822* two: function(callback) {3823* setTimeout(function() {3824* callback(null, 2);3825* }, 100);3826* }3827* });3828* console.log(results);3829* // results is equal to: { one: 1, two: 2 }3830* }3831* catch (err) {3832* console.log(err);3833* }3834* }3835*3836*/3837function parallel(tasks, callback) {3838return _parallel(eachOf$1, tasks, callback);3839}38403841/**3842* The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a3843* time.3844*3845* @name parallelLimit3846* @static3847* @memberOf module:ControlFlow3848* @method3849* @see [async.parallel]{@link module:ControlFlow.parallel}3850* @category Control Flow3851* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of3852* [async functions]{@link AsyncFunction} to run.3853* Each async function can complete with any number of optional `result` values.3854* @param {number} limit - The maximum number of async operations at a time.3855* @param {Function} [callback] - An optional callback to run once all the3856* functions have completed successfully. This function gets a results array3857* (or object) containing all the result arguments passed to the task callbacks.3858* Invoked with (err, results).3859* @returns {Promise} a promise, if a callback is not passed3860*/3861function parallelLimit(tasks, limit, callback) {3862return _parallel(eachOfLimit(limit), tasks, callback);3863}38643865/**3866* A queue of tasks for the worker function to complete.3867* @typedef {Iterable} QueueObject3868* @memberOf module:ControlFlow3869* @property {Function} length - a function returning the number of items3870* waiting to be processed. Invoke with `queue.length()`.3871* @property {boolean} started - a boolean indicating whether or not any3872* items have been pushed and processed by the queue.3873* @property {Function} running - a function returning the number of items3874* currently being processed. Invoke with `queue.running()`.3875* @property {Function} workersList - a function returning the array of items3876* currently being processed. Invoke with `queue.workersList()`.3877* @property {Function} idle - a function returning false if there are items3878* waiting or being processed, or true if not. Invoke with `queue.idle()`.3879* @property {number} concurrency - an integer for determining how many `worker`3880* functions should be run in parallel. This property can be changed after a3881* `queue` is created to alter the concurrency on-the-fly.3882* @property {number} payload - an integer that specifies how many items are3883* passed to the worker function at a time. only applies if this is a3884* [cargo]{@link module:ControlFlow.cargo} object3885* @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`3886* once the `worker` has finished processing the task. Instead of a single task,3887* a `tasks` array can be submitted. The respective callback is used for every3888* task in the list. Invoke with `queue.push(task, [callback])`,3889* @property {AsyncFunction} unshift - add a new task to the front of the `queue`.3890* Invoke with `queue.unshift(task, [callback])`.3891* @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns3892* a promise that rejects if an error occurs.3893* @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns3894* a promise that rejects if an error occurs.3895* @property {Function} remove - remove items from the queue that match a test3896* function. The test function will be passed an object with a `data` property,3897* and a `priority` property, if this is a3898* [priorityQueue]{@link module:ControlFlow.priorityQueue} object.3899* Invoked with `queue.remove(testFn)`, where `testFn` is of the form3900* `function ({data, priority}) {}` and returns a Boolean.3901* @property {Function} saturated - a function that sets a callback that is3902* called when the number of running workers hits the `concurrency` limit, and3903* further tasks will be queued. If the callback is omitted, `q.saturated()`3904* returns a promise for the next occurrence.3905* @property {Function} unsaturated - a function that sets a callback that is3906* called when the number of running workers is less than the `concurrency` &3907* `buffer` limits, and further tasks will not be queued. If the callback is3908* omitted, `q.unsaturated()` returns a promise for the next occurrence.3909* @property {number} buffer - A minimum threshold buffer in order to say that3910* the `queue` is `unsaturated`.3911* @property {Function} empty - a function that sets a callback that is called3912* when the last item from the `queue` is given to a `worker`. If the callback3913* is omitted, `q.empty()` returns a promise for the next occurrence.3914* @property {Function} drain - a function that sets a callback that is called3915* when the last item from the `queue` has returned from the `worker`. If the3916* callback is omitted, `q.drain()` returns a promise for the next occurrence.3917* @property {Function} error - a function that sets a callback that is called3918* when a task errors. Has the signature `function(error, task)`. If the3919* callback is omitted, `error()` returns a promise that rejects on the next3920* error.3921* @property {boolean} paused - a boolean for determining whether the queue is3922* in a paused state.3923* @property {Function} pause - a function that pauses the processing of tasks3924* until `resume()` is called. Invoke with `queue.pause()`.3925* @property {Function} resume - a function that resumes the processing of3926* queued tasks when the queue is paused. Invoke with `queue.resume()`.3927* @property {Function} kill - a function that removes the `drain` callback and3928* empties remaining tasks from the queue forcing it to go idle. No more tasks3929* should be pushed to the queue after calling this function. Invoke with `queue.kill()`.3930*3931* @example3932* const q = async.queue(worker, 2)3933* q.push(item1)3934* q.push(item2)3935* q.push(item3)3936* // queues are iterable, spread into an array to inspect3937* const items = [...q] // [item1, item2, item3]3938* // or use for of3939* for (let item of q) {3940* console.log(item)3941* }3942*3943* q.drain(() => {3944* console.log('all done')3945* })3946* // or3947* await q.drain()3948*/39493950/**3951* Creates a `queue` object with the specified `concurrency`. Tasks added to the3952* `queue` are processed in parallel (up to the `concurrency` limit). If all3953* `worker`s are in progress, the task is queued until one becomes available.3954* Once a `worker` completes a `task`, that `task`'s callback is called.3955*3956* @name queue3957* @static3958* @memberOf module:ControlFlow3959* @method3960* @category Control Flow3961* @param {AsyncFunction} worker - An async function for processing a queued task.3962* If you want to handle errors from an individual task, pass a callback to3963* `q.push()`. Invoked with (task, callback).3964* @param {number} [concurrency=1] - An `integer` for determining how many3965* `worker` functions should be run in parallel. If omitted, the concurrency3966* defaults to `1`. If the concurrency is `0`, an error is thrown.3967* @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be3968* attached as certain properties to listen for specific events during the3969* lifecycle of the queue.3970* @example3971*3972* // create a queue object with concurrency 23973* var q = async.queue(function(task, callback) {3974* console.log('hello ' + task.name);3975* callback();3976* }, 2);3977*3978* // assign a callback3979* q.drain(function() {3980* console.log('all items have been processed');3981* });3982* // or await the end3983* await q.drain()3984*3985* // assign an error callback3986* q.error(function(err, task) {3987* console.error('task experienced an error');3988* });3989*3990* // add some items to the queue3991* q.push({name: 'foo'}, function(err) {3992* console.log('finished processing foo');3993* });3994* // callback is optional3995* q.push({name: 'bar'});3996*3997* // add some items to the queue (batch-wise)3998* q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {3999* console.log('finished processing item');4000* });4001*4002* // add some items to the front of the queue4003* q.unshift({name: 'bar'}, function (err) {4004* console.log('finished processing bar');4005* });4006*/4007function queue$1 (worker, concurrency) {4008var _worker = wrapAsync(worker);4009return queue((items, cb) => {4010_worker(items[0], cb);4011}, concurrency, 1);4012}40134014// Binary min-heap implementation used for priority queue.4015// Implementation is stable, i.e. push time is considered for equal priorities4016class Heap {4017constructor() {4018this.heap = [];4019this.pushCount = Number.MIN_SAFE_INTEGER;4020}40214022get length() {4023return this.heap.length;4024}40254026empty () {4027this.heap = [];4028return this;4029}40304031percUp(index) {4032let p;40334034while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {4035let t = this.heap[index];4036this.heap[index] = this.heap[p];4037this.heap[p] = t;40384039index = p;4040}4041}40424043percDown(index) {4044let l;40454046while ((l=leftChi(index)) < this.heap.length) {4047if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {4048l = l+1;4049}40504051if (smaller(this.heap[index], this.heap[l])) {4052break;4053}40544055let t = this.heap[index];4056this.heap[index] = this.heap[l];4057this.heap[l] = t;40584059index = l;4060}4061}40624063push(node) {4064node.pushCount = ++this.pushCount;4065this.heap.push(node);4066this.percUp(this.heap.length-1);4067}40684069unshift(node) {4070return this.heap.push(node);4071}40724073shift() {4074let [top] = this.heap;40754076this.heap[0] = this.heap[this.heap.length-1];4077this.heap.pop();4078this.percDown(0);40794080return top;4081}40824083toArray() {4084return [...this];4085}40864087*[Symbol.iterator] () {4088for (let i = 0; i < this.heap.length; i++) {4089yield this.heap[i].data;4090}4091}40924093remove (testFn) {4094let j = 0;4095for (let i = 0; i < this.heap.length; i++) {4096if (!testFn(this.heap[i])) {4097this.heap[j] = this.heap[i];4098j++;4099}4100}41014102this.heap.splice(j);41034104for (let i = parent(this.heap.length-1); i >= 0; i--) {4105this.percDown(i);4106}41074108return this;4109}4110}41114112function leftChi(i) {4113return (i<<1)+1;4114}41154116function parent(i) {4117return ((i+1)>>1)-1;4118}41194120function smaller(x, y) {4121if (x.priority !== y.priority) {4122return x.priority < y.priority;4123}4124else {4125return x.pushCount < y.pushCount;4126}4127}41284129/**4130* The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and4131* completed in ascending priority order.4132*4133* @name priorityQueue4134* @static4135* @memberOf module:ControlFlow4136* @method4137* @see [async.queue]{@link module:ControlFlow.queue}4138* @category Control Flow4139* @param {AsyncFunction} worker - An async function for processing a queued task.4140* If you want to handle errors from an individual task, pass a callback to4141* `q.push()`.4142* Invoked with (task, callback).4143* @param {number} concurrency - An `integer` for determining how many `worker`4144* functions should be run in parallel. If omitted, the concurrency defaults to4145* `1`. If the concurrency is `0`, an error is thrown.4146* @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two4147* differences between `queue` and `priorityQueue` objects:4148* * `push(task, priority, [callback])` - `priority` should be a number. If an4149* array of `tasks` is given, all tasks will be assigned the same priority.4150* * The `unshift` method was removed.4151*/4152function priorityQueue(worker, concurrency) {4153// Start with a normal queue4154var q = queue$1(worker, concurrency);4155var processingScheduled = false;41564157q._tasks = new Heap();41584159// Override push to accept second parameter representing priority4160q.push = function(data, priority = 0, callback = () => {}) {4161if (typeof callback !== 'function') {4162throw new Error('task callback must be a function');4163}4164q.started = true;4165if (!Array.isArray(data)) {4166data = [data];4167}4168if (data.length === 0 && q.idle()) {4169// call drain immediately if there are no tasks4170return setImmediate$1(() => q.drain());4171}41724173for (var i = 0, l = data.length; i < l; i++) {4174var item = {4175data: data[i],4176priority,4177callback4178};41794180q._tasks.push(item);4181}41824183if (!processingScheduled) {4184processingScheduled = true;4185setImmediate$1(() => {4186processingScheduled = false;4187q.process();4188});4189}4190};41914192// Remove unshift function4193delete q.unshift;41944195return q;4196}41974198/**4199* Runs the `tasks` array of functions in parallel, without waiting until the4200* previous function has completed. Once any of the `tasks` complete or pass an4201* error to its callback, the main `callback` is immediately called. It's4202* equivalent to `Promise.race()`.4203*4204* @name race4205* @static4206* @memberOf module:ControlFlow4207* @method4208* @category Control Flow4209* @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}4210* to run. Each function can complete with an optional `result` value.4211* @param {Function} callback - A callback to run once any of the functions have4212* completed. This function gets an error or result from the first function that4213* completed. Invoked with (err, result).4214* @returns undefined4215* @example4216*4217* async.race([4218* function(callback) {4219* setTimeout(function() {4220* callback(null, 'one');4221* }, 200);4222* },4223* function(callback) {4224* setTimeout(function() {4225* callback(null, 'two');4226* }, 100);4227* }4228* ],4229* // main callback4230* function(err, result) {4231* // the result will be equal to 'two' as it finishes earlier4232* });4233*/4234function race(tasks, callback) {4235callback = once(callback);4236if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));4237if (!tasks.length) return callback();4238for (var i = 0, l = tasks.length; i < l; i++) {4239wrapAsync(tasks[i])(callback);4240}4241}42424243var race$1 = awaitify(race, 2);42444245/**4246* Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.4247*4248* @name reduceRight4249* @static4250* @memberOf module:Collections4251* @method4252* @see [async.reduce]{@link module:Collections.reduce}4253* @alias foldr4254* @category Collection4255* @param {Array} array - A collection to iterate over.4256* @param {*} memo - The initial state of the reduction.4257* @param {AsyncFunction} iteratee - A function applied to each item in the4258* array to produce the next step in the reduction.4259* The `iteratee` should complete with the next state of the reduction.4260* If the iteratee completes with an error, the reduction is stopped and the4261* main `callback` is immediately called with the error.4262* Invoked with (memo, item, callback).4263* @param {Function} [callback] - A callback which is called after all the4264* `iteratee` functions have finished. Result is the reduced value. Invoked with4265* (err, result).4266* @returns {Promise} a promise, if no callback is passed4267*/4268function reduceRight (array, memo, iteratee, callback) {4269var reversed = [...array].reverse();4270return reduce$1(reversed, memo, iteratee, callback);4271}42724273/**4274* Wraps the async function in another function that always completes with a4275* result object, even when it errors.4276*4277* The result object has either the property `error` or `value`.4278*4279* @name reflect4280* @static4281* @memberOf module:Utils4282* @method4283* @category Util4284* @param {AsyncFunction} fn - The async function you want to wrap4285* @returns {Function} - A function that always passes null to it's callback as4286* the error. The second argument to the callback will be an `object` with4287* either an `error` or a `value` property.4288* @example4289*4290* async.parallel([4291* async.reflect(function(callback) {4292* // do some stuff ...4293* callback(null, 'one');4294* }),4295* async.reflect(function(callback) {4296* // do some more stuff but error ...4297* callback('bad stuff happened');4298* }),4299* async.reflect(function(callback) {4300* // do some more stuff ...4301* callback(null, 'two');4302* })4303* ],4304* // optional callback4305* function(err, results) {4306* // values4307* // results[0].value = 'one'4308* // results[1].error = 'bad stuff happened'4309* // results[2].value = 'two'4310* });4311*/4312function reflect(fn) {4313var _fn = wrapAsync(fn);4314return initialParams(function reflectOn(args, reflectCallback) {4315args.push((error, ...cbArgs) => {4316let retVal = {};4317if (error) {4318retVal.error = error;4319}4320if (cbArgs.length > 0){4321var value = cbArgs;4322if (cbArgs.length <= 1) {4323[value] = cbArgs;4324}4325retVal.value = value;4326}4327reflectCallback(null, retVal);4328});43294330return _fn.apply(this, args);4331});4332}43334334/**4335* A helper function that wraps an array or an object of functions with `reflect`.4336*4337* @name reflectAll4338* @static4339* @memberOf module:Utils4340* @method4341* @see [async.reflect]{@link module:Utils.reflect}4342* @category Util4343* @param {Array|Object|Iterable} tasks - The collection of4344* [async functions]{@link AsyncFunction} to wrap in `async.reflect`.4345* @returns {Array} Returns an array of async functions, each wrapped in4346* `async.reflect`4347* @example4348*4349* let tasks = [4350* function(callback) {4351* setTimeout(function() {4352* callback(null, 'one');4353* }, 200);4354* },4355* function(callback) {4356* // do some more stuff but error ...4357* callback(new Error('bad stuff happened'));4358* },4359* function(callback) {4360* setTimeout(function() {4361* callback(null, 'two');4362* }, 100);4363* }4364* ];4365*4366* async.parallel(async.reflectAll(tasks),4367* // optional callback4368* function(err, results) {4369* // values4370* // results[0].value = 'one'4371* // results[1].error = Error('bad stuff happened')4372* // results[2].value = 'two'4373* });4374*4375* // an example using an object instead of an array4376* let tasks = {4377* one: function(callback) {4378* setTimeout(function() {4379* callback(null, 'one');4380* }, 200);4381* },4382* two: function(callback) {4383* callback('two');4384* },4385* three: function(callback) {4386* setTimeout(function() {4387* callback(null, 'three');4388* }, 100);4389* }4390* };4391*4392* async.parallel(async.reflectAll(tasks),4393* // optional callback4394* function(err, results) {4395* // values4396* // results.one.value = 'one'4397* // results.two.error = 'two'4398* // results.three.value = 'three'4399* });4400*/4401function reflectAll(tasks) {4402var results;4403if (Array.isArray(tasks)) {4404results = tasks.map(reflect);4405} else {4406results = {};4407Object.keys(tasks).forEach(key => {4408results[key] = reflect.call(this, tasks[key]);4409});4410}4411return results;4412}44134414function reject(eachfn, arr, _iteratee, callback) {4415const iteratee = wrapAsync(_iteratee);4416return _filter(eachfn, arr, (value, cb) => {4417iteratee(value, (err, v) => {4418cb(err, !v);4419});4420}, callback);4421}44224423/**4424* The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.4425*4426* @name reject4427* @static4428* @memberOf module:Collections4429* @method4430* @see [async.filter]{@link module:Collections.filter}4431* @category Collection4432* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4433* @param {Function} iteratee - An async truth test to apply to each item in4434* `coll`.4435* The should complete with a boolean value as its `result`.4436* Invoked with (item, callback).4437* @param {Function} [callback] - A callback which is called after all the4438* `iteratee` functions have finished. Invoked with (err, results).4439* @returns {Promise} a promise, if no callback is passed4440* @example4441*4442* // dir1 is a directory that contains file1.txt, file2.txt4443* // dir2 is a directory that contains file3.txt, file4.txt4444* // dir3 is a directory that contains file5.txt4445*4446* const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];4447*4448* // asynchronous function that checks if a file exists4449* function fileExists(file, callback) {4450* fs.access(file, fs.constants.F_OK, (err) => {4451* callback(null, !err);4452* });4453* }4454*4455* // Using callbacks4456* async.reject(fileList, fileExists, function(err, results) {4457* // [ 'dir3/file6.txt' ]4458* // results now equals an array of the non-existing files4459* });4460*4461* // Using Promises4462* async.reject(fileList, fileExists)4463* .then( results => {4464* console.log(results);4465* // [ 'dir3/file6.txt' ]4466* // results now equals an array of the non-existing files4467* }).catch( err => {4468* console.log(err);4469* });4470*4471* // Using async/await4472* async () => {4473* try {4474* let results = await async.reject(fileList, fileExists);4475* console.log(results);4476* // [ 'dir3/file6.txt' ]4477* // results now equals an array of the non-existing files4478* }4479* catch (err) {4480* console.log(err);4481* }4482* }4483*4484*/4485function reject$1 (coll, iteratee, callback) {4486return reject(eachOf$1, coll, iteratee, callback)4487}4488var reject$2 = awaitify(reject$1, 3);44894490/**4491* The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a4492* time.4493*4494* @name rejectLimit4495* @static4496* @memberOf module:Collections4497* @method4498* @see [async.reject]{@link module:Collections.reject}4499* @category Collection4500* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4501* @param {number} limit - The maximum number of async operations at a time.4502* @param {Function} iteratee - An async truth test to apply to each item in4503* `coll`.4504* The should complete with a boolean value as its `result`.4505* Invoked with (item, callback).4506* @param {Function} [callback] - A callback which is called after all the4507* `iteratee` functions have finished. Invoked with (err, results).4508* @returns {Promise} a promise, if no callback is passed4509*/4510function rejectLimit (coll, limit, iteratee, callback) {4511return reject(eachOfLimit(limit), coll, iteratee, callback)4512}4513var rejectLimit$1 = awaitify(rejectLimit, 4);45144515/**4516* The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.4517*4518* @name rejectSeries4519* @static4520* @memberOf module:Collections4521* @method4522* @see [async.reject]{@link module:Collections.reject}4523* @category Collection4524* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4525* @param {Function} iteratee - An async truth test to apply to each item in4526* `coll`.4527* The should complete with a boolean value as its `result`.4528* Invoked with (item, callback).4529* @param {Function} [callback] - A callback which is called after all the4530* `iteratee` functions have finished. Invoked with (err, results).4531* @returns {Promise} a promise, if no callback is passed4532*/4533function rejectSeries (coll, iteratee, callback) {4534return reject(eachOfSeries$1, coll, iteratee, callback)4535}4536var rejectSeries$1 = awaitify(rejectSeries, 3);45374538function constant$1(value) {4539return function () {4540return value;4541}4542}45434544/**4545* Attempts to get a successful response from `task` no more than `times` times4546* before returning an error. If the task is successful, the `callback` will be4547* passed the result of the successful task. If all attempts fail, the callback4548* will be passed the error and result (if any) of the final attempt.4549*4550* @name retry4551* @static4552* @memberOf module:ControlFlow4553* @method4554* @category Control Flow4555* @see [async.retryable]{@link module:ControlFlow.retryable}4556* @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an4557* object with `times` and `interval` or a number.4558* * `times` - The number of attempts to make before giving up. The default4559* is `5`.4560* * `interval` - The time to wait between retries, in milliseconds. The4561* default is `0`. The interval may also be specified as a function of the4562* retry count (see example).4563* * `errorFilter` - An optional synchronous function that is invoked on4564* erroneous result. If it returns `true` the retry attempts will continue;4565* if the function returns `false` the retry flow is aborted with the current4566* attempt's error and result being returned to the final callback.4567* Invoked with (err).4568* * If `opts` is a number, the number specifies the number of times to retry,4569* with the default interval of `0`.4570* @param {AsyncFunction} task - An async function to retry.4571* Invoked with (callback).4572* @param {Function} [callback] - An optional callback which is called when the4573* task has succeeded, or after the final failed attempt. It receives the `err`4574* and `result` arguments of the last attempt at completing the `task`. Invoked4575* with (err, results).4576* @returns {Promise} a promise if no callback provided4577*4578* @example4579*4580* // The `retry` function can be used as a stand-alone control flow by passing4581* // a callback, as shown below:4582*4583* // try calling apiMethod 3 times4584* async.retry(3, apiMethod, function(err, result) {4585* // do something with the result4586* });4587*4588* // try calling apiMethod 3 times, waiting 200 ms between each retry4589* async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {4590* // do something with the result4591* });4592*4593* // try calling apiMethod 10 times with exponential backoff4594* // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)4595* async.retry({4596* times: 10,4597* interval: function(retryCount) {4598* return 50 * Math.pow(2, retryCount);4599* }4600* }, apiMethod, function(err, result) {4601* // do something with the result4602* });4603*4604* // try calling apiMethod the default 5 times no delay between each retry4605* async.retry(apiMethod, function(err, result) {4606* // do something with the result4607* });4608*4609* // try calling apiMethod only when error condition satisfies, all other4610* // errors will abort the retry control flow and return to final callback4611* async.retry({4612* errorFilter: function(err) {4613* return err.message === 'Temporary error'; // only retry on a specific error4614* }4615* }, apiMethod, function(err, result) {4616* // do something with the result4617* });4618*4619* // to retry individual methods that are not as reliable within other4620* // control flow functions, use the `retryable` wrapper:4621* async.auto({4622* users: api.getUsers.bind(api),4623* payments: async.retryable(3, api.getPayments.bind(api))4624* }, function(err, results) {4625* // do something with the results4626* });4627*4628*/4629const DEFAULT_TIMES = 5;4630const DEFAULT_INTERVAL = 0;46314632function retry(opts, task, callback) {4633var options = {4634times: DEFAULT_TIMES,4635intervalFunc: constant$1(DEFAULT_INTERVAL)4636};46374638if (arguments.length < 3 && typeof opts === 'function') {4639callback = task || promiseCallback();4640task = opts;4641} else {4642parseTimes(options, opts);4643callback = callback || promiseCallback();4644}46454646if (typeof task !== 'function') {4647throw new Error("Invalid arguments for async.retry");4648}46494650var _task = wrapAsync(task);46514652var attempt = 1;4653function retryAttempt() {4654_task((err, ...args) => {4655if (err === false) return4656if (err && attempt++ < options.times &&4657(typeof options.errorFilter != 'function' ||4658options.errorFilter(err))) {4659setTimeout(retryAttempt, options.intervalFunc(attempt - 1));4660} else {4661callback(err, ...args);4662}4663});4664}46654666retryAttempt();4667return callback[PROMISE_SYMBOL]4668}46694670function parseTimes(acc, t) {4671if (typeof t === 'object') {4672acc.times = +t.times || DEFAULT_TIMES;46734674acc.intervalFunc = typeof t.interval === 'function' ?4675t.interval :4676constant$1(+t.interval || DEFAULT_INTERVAL);46774678acc.errorFilter = t.errorFilter;4679} else if (typeof t === 'number' || typeof t === 'string') {4680acc.times = +t || DEFAULT_TIMES;4681} else {4682throw new Error("Invalid arguments for async.retry");4683}4684}46854686/**4687* A close relative of [`retry`]{@link module:ControlFlow.retry}. This method4688* wraps a task and makes it retryable, rather than immediately calling it4689* with retries.4690*4691* @name retryable4692* @static4693* @memberOf module:ControlFlow4694* @method4695* @see [async.retry]{@link module:ControlFlow.retry}4696* @category Control Flow4697* @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional4698* options, exactly the same as from `retry`, except for a `opts.arity` that4699* is the arity of the `task` function, defaulting to `task.length`4700* @param {AsyncFunction} task - the asynchronous function to wrap.4701* This function will be passed any arguments passed to the returned wrapper.4702* Invoked with (...args, callback).4703* @returns {AsyncFunction} The wrapped function, which when invoked, will4704* retry on an error, based on the parameters specified in `opts`.4705* This function will accept the same parameters as `task`.4706* @example4707*4708* async.auto({4709* dep1: async.retryable(3, getFromFlakyService),4710* process: ["dep1", async.retryable(3, function (results, cb) {4711* maybeProcessData(results.dep1, cb);4712* })]4713* }, callback);4714*/4715function retryable (opts, task) {4716if (!task) {4717task = opts;4718opts = null;4719}4720let arity = (opts && opts.arity) || task.length;4721if (isAsync(task)) {4722arity += 1;4723}4724var _task = wrapAsync(task);4725return initialParams((args, callback) => {4726if (args.length < arity - 1 || callback == null) {4727args.push(callback);4728callback = promiseCallback();4729}4730function taskFn(cb) {4731_task(...args, cb);4732}47334734if (opts) retry(opts, taskFn, callback);4735else retry(taskFn, callback);47364737return callback[PROMISE_SYMBOL]4738});4739}47404741/**4742* Run the functions in the `tasks` collection in series, each one running once4743* the previous function has completed. If any functions in the series pass an4744* error to its callback, no more functions are run, and `callback` is4745* immediately called with the value of the error. Otherwise, `callback`4746* receives an array of results when `tasks` have completed.4747*4748* It is also possible to use an object instead of an array. Each property will4749* be run as a function, and the results will be passed to the final `callback`4750* as an object instead of an array. This can be a more readable way of handling4751* results from {@link async.series}.4752*4753* **Note** that while many implementations preserve the order of object4754* properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)4755* explicitly states that4756*4757* > The mechanics and order of enumerating the properties is not specified.4758*4759* So if you rely on the order in which your series of functions are executed,4760* and want this to work on all platforms, consider using an array.4761*4762* @name series4763* @static4764* @memberOf module:ControlFlow4765* @method4766* @category Control Flow4767* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing4768* [async functions]{@link AsyncFunction} to run in series.4769* Each function can complete with any number of optional `result` values.4770* @param {Function} [callback] - An optional callback to run once all the4771* functions have completed. This function gets a results array (or object)4772* containing all the result arguments passed to the `task` callbacks. Invoked4773* with (err, result).4774* @return {Promise} a promise, if no callback is passed4775* @example4776*4777* //Using Callbacks4778* async.series([4779* function(callback) {4780* setTimeout(function() {4781* // do some async task4782* callback(null, 'one');4783* }, 200);4784* },4785* function(callback) {4786* setTimeout(function() {4787* // then do another async task4788* callback(null, 'two');4789* }, 100);4790* }4791* ], function(err, results) {4792* console.log(results);4793* // results is equal to ['one','two']4794* });4795*4796* // an example using objects instead of arrays4797* async.series({4798* one: function(callback) {4799* setTimeout(function() {4800* // do some async task4801* callback(null, 1);4802* }, 200);4803* },4804* two: function(callback) {4805* setTimeout(function() {4806* // then do another async task4807* callback(null, 2);4808* }, 100);4809* }4810* }, function(err, results) {4811* console.log(results);4812* // results is equal to: { one: 1, two: 2 }4813* });4814*4815* //Using Promises4816* async.series([4817* function(callback) {4818* setTimeout(function() {4819* callback(null, 'one');4820* }, 200);4821* },4822* function(callback) {4823* setTimeout(function() {4824* callback(null, 'two');4825* }, 100);4826* }4827* ]).then(results => {4828* console.log(results);4829* // results is equal to ['one','two']4830* }).catch(err => {4831* console.log(err);4832* });4833*4834* // an example using an object instead of an array4835* async.series({4836* one: function(callback) {4837* setTimeout(function() {4838* // do some async task4839* callback(null, 1);4840* }, 200);4841* },4842* two: function(callback) {4843* setTimeout(function() {4844* // then do another async task4845* callback(null, 2);4846* }, 100);4847* }4848* }).then(results => {4849* console.log(results);4850* // results is equal to: { one: 1, two: 2 }4851* }).catch(err => {4852* console.log(err);4853* });4854*4855* //Using async/await4856* async () => {4857* try {4858* let results = await async.series([4859* function(callback) {4860* setTimeout(function() {4861* // do some async task4862* callback(null, 'one');4863* }, 200);4864* },4865* function(callback) {4866* setTimeout(function() {4867* // then do another async task4868* callback(null, 'two');4869* }, 100);4870* }4871* ]);4872* console.log(results);4873* // results is equal to ['one','two']4874* }4875* catch (err) {4876* console.log(err);4877* }4878* }4879*4880* // an example using an object instead of an array4881* async () => {4882* try {4883* let results = await async.parallel({4884* one: function(callback) {4885* setTimeout(function() {4886* // do some async task4887* callback(null, 1);4888* }, 200);4889* },4890* two: function(callback) {4891* setTimeout(function() {4892* // then do another async task4893* callback(null, 2);4894* }, 100);4895* }4896* });4897* console.log(results);4898* // results is equal to: { one: 1, two: 2 }4899* }4900* catch (err) {4901* console.log(err);4902* }4903* }4904*4905*/4906function series(tasks, callback) {4907return _parallel(eachOfSeries$1, tasks, callback);4908}49094910/**4911* Returns `true` if at least one element in the `coll` satisfies an async test.4912* If any iteratee call returns `true`, the main `callback` is immediately4913* called.4914*4915* @name some4916* @static4917* @memberOf module:Collections4918* @method4919* @alias any4920* @category Collection4921* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.4922* @param {AsyncFunction} iteratee - An async truth test to apply to each item4923* in the collections in parallel.4924* The iteratee should complete with a boolean `result` value.4925* Invoked with (item, callback).4926* @param {Function} [callback] - A callback which is called as soon as any4927* iteratee returns `true`, or after all the iteratee functions have finished.4928* Result will be either `true` or `false` depending on the values of the async4929* tests. Invoked with (err, result).4930* @returns {Promise} a promise, if no callback provided4931* @example4932*4933* // dir1 is a directory that contains file1.txt, file2.txt4934* // dir2 is a directory that contains file3.txt, file4.txt4935* // dir3 is a directory that contains file5.txt4936* // dir4 does not exist4937*4938* // asynchronous function that checks if a file exists4939* function fileExists(file, callback) {4940* fs.access(file, fs.constants.F_OK, (err) => {4941* callback(null, !err);4942* });4943* }4944*4945* // Using callbacks4946* async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,4947* function(err, result) {4948* console.log(result);4949* // true4950* // result is true since some file in the list exists4951* }4952*);4953*4954* async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,4955* function(err, result) {4956* console.log(result);4957* // false4958* // result is false since none of the files exists4959* }4960*);4961*4962* // Using Promises4963* async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)4964* .then( result => {4965* console.log(result);4966* // true4967* // result is true since some file in the list exists4968* }).catch( err => {4969* console.log(err);4970* });4971*4972* async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)4973* .then( result => {4974* console.log(result);4975* // false4976* // result is false since none of the files exists4977* }).catch( err => {4978* console.log(err);4979* });4980*4981* // Using async/await4982* async () => {4983* try {4984* let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);4985* console.log(result);4986* // true4987* // result is true since some file in the list exists4988* }4989* catch (err) {4990* console.log(err);4991* }4992* }4993*4994* async () => {4995* try {4996* let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);4997* console.log(result);4998* // false4999* // result is false since none of the files exists5000* }5001* catch (err) {5002* console.log(err);5003* }5004* }5005*5006*/5007function some(coll, iteratee, callback) {5008return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)5009}5010var some$1 = awaitify(some, 3);50115012/**5013* The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.5014*5015* @name someLimit5016* @static5017* @memberOf module:Collections5018* @method5019* @see [async.some]{@link module:Collections.some}5020* @alias anyLimit5021* @category Collection5022* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5023* @param {number} limit - The maximum number of async operations at a time.5024* @param {AsyncFunction} iteratee - An async truth test to apply to each item5025* in the collections in parallel.5026* The iteratee should complete with a boolean `result` value.5027* Invoked with (item, callback).5028* @param {Function} [callback] - A callback which is called as soon as any5029* iteratee returns `true`, or after all the iteratee functions have finished.5030* Result will be either `true` or `false` depending on the values of the async5031* tests. Invoked with (err, result).5032* @returns {Promise} a promise, if no callback provided5033*/5034function someLimit(coll, limit, iteratee, callback) {5035return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback)5036}5037var someLimit$1 = awaitify(someLimit, 4);50385039/**5040* The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.5041*5042* @name someSeries5043* @static5044* @memberOf module:Collections5045* @method5046* @see [async.some]{@link module:Collections.some}5047* @alias anySeries5048* @category Collection5049* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5050* @param {AsyncFunction} iteratee - An async truth test to apply to each item5051* in the collections in series.5052* The iteratee should complete with a boolean `result` value.5053* Invoked with (item, callback).5054* @param {Function} [callback] - A callback which is called as soon as any5055* iteratee returns `true`, or after all the iteratee functions have finished.5056* Result will be either `true` or `false` depending on the values of the async5057* tests. Invoked with (err, result).5058* @returns {Promise} a promise, if no callback provided5059*/5060function someSeries(coll, iteratee, callback) {5061return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)5062}5063var someSeries$1 = awaitify(someSeries, 3);50645065/**5066* Sorts a list by the results of running each `coll` value through an async5067* `iteratee`.5068*5069* @name sortBy5070* @static5071* @memberOf module:Collections5072* @method5073* @category Collection5074* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5075* @param {AsyncFunction} iteratee - An async function to apply to each item in5076* `coll`.5077* The iteratee should complete with a value to use as the sort criteria as5078* its `result`.5079* Invoked with (item, callback).5080* @param {Function} callback - A callback which is called after all the5081* `iteratee` functions have finished, or an error occurs. Results is the items5082* from the original `coll` sorted by the values returned by the `iteratee`5083* calls. Invoked with (err, results).5084* @returns {Promise} a promise, if no callback passed5085* @example5086*5087* // bigfile.txt is a file that is 251100 bytes in size5088* // mediumfile.txt is a file that is 11000 bytes in size5089* // smallfile.txt is a file that is 121 bytes in size5090*5091* // asynchronous function that returns the file size in bytes5092* function getFileSizeInBytes(file, callback) {5093* fs.stat(file, function(err, stat) {5094* if (err) {5095* return callback(err);5096* }5097* callback(null, stat.size);5098* });5099* }5100*5101* // Using callbacks5102* async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,5103* function(err, results) {5104* if (err) {5105* console.log(err);5106* } else {5107* console.log(results);5108* // results is now the original array of files sorted by5109* // file size (ascending by default), e.g.5110* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5111* }5112* }5113* );5114*5115* // By modifying the callback parameter the5116* // sorting order can be influenced:5117*5118* // ascending order5119* async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {5120* getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {5121* if (getFileSizeErr) return callback(getFileSizeErr);5122* callback(null, fileSize);5123* });5124* }, function(err, results) {5125* if (err) {5126* console.log(err);5127* } else {5128* console.log(results);5129* // results is now the original array of files sorted by5130* // file size (ascending by default), e.g.5131* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5132* }5133* }5134* );5135*5136* // descending order5137* async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {5138* getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {5139* if (getFileSizeErr) {5140* return callback(getFileSizeErr);5141* }5142* callback(null, fileSize * -1);5143* });5144* }, function(err, results) {5145* if (err) {5146* console.log(err);5147* } else {5148* console.log(results);5149* // results is now the original array of files sorted by5150* // file size (ascending by default), e.g.5151* // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']5152* }5153* }5154* );5155*5156* // Error handling5157* async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,5158* function(err, results) {5159* if (err) {5160* console.log(err);5161* // [ Error: ENOENT: no such file or directory ]5162* } else {5163* console.log(results);5164* }5165* }5166* );5167*5168* // Using Promises5169* async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)5170* .then( results => {5171* console.log(results);5172* // results is now the original array of files sorted by5173* // file size (ascending by default), e.g.5174* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5175* }).catch( err => {5176* console.log(err);5177* });5178*5179* // Error handling5180* async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)5181* .then( results => {5182* console.log(results);5183* }).catch( err => {5184* console.log(err);5185* // [ Error: ENOENT: no such file or directory ]5186* });5187*5188* // Using async/await5189* (async () => {5190* try {5191* let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);5192* console.log(results);5193* // results is now the original array of files sorted by5194* // file size (ascending by default), e.g.5195* // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']5196* }5197* catch (err) {5198* console.log(err);5199* }5200* })();5201*5202* // Error handling5203* async () => {5204* try {5205* let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);5206* console.log(results);5207* }5208* catch (err) {5209* console.log(err);5210* // [ Error: ENOENT: no such file or directory ]5211* }5212* }5213*5214*/5215function sortBy (coll, iteratee, callback) {5216var _iteratee = wrapAsync(iteratee);5217return map$1(coll, (x, iterCb) => {5218_iteratee(x, (err, criteria) => {5219if (err) return iterCb(err);5220iterCb(err, {value: x, criteria});5221});5222}, (err, results) => {5223if (err) return callback(err);5224callback(null, results.sort(comparator).map(v => v.value));5225});52265227function comparator(left, right) {5228var a = left.criteria, b = right.criteria;5229return a < b ? -1 : a > b ? 1 : 0;5230}5231}5232var sortBy$1 = awaitify(sortBy, 3);52335234/**5235* Sets a time limit on an asynchronous function. If the function does not call5236* its callback within the specified milliseconds, it will be called with a5237* timeout error. The code property for the error object will be `'ETIMEDOUT'`.5238*5239* @name timeout5240* @static5241* @memberOf module:Utils5242* @method5243* @category Util5244* @param {AsyncFunction} asyncFn - The async function to limit in time.5245* @param {number} milliseconds - The specified time limit.5246* @param {*} [info] - Any variable you want attached (`string`, `object`, etc)5247* to timeout Error for more information..5248* @returns {AsyncFunction} Returns a wrapped function that can be used with any5249* of the control flow functions.5250* Invoke this function with the same parameters as you would `asyncFunc`.5251* @example5252*5253* function myFunction(foo, callback) {5254* doAsyncTask(foo, function(err, data) {5255* // handle errors5256* if (err) return callback(err);5257*5258* // do some stuff ...5259*5260* // return processed data5261* return callback(null, data);5262* });5263* }5264*5265* var wrapped = async.timeout(myFunction, 1000);5266*5267* // call `wrapped` as you would `myFunction`5268* wrapped({ bar: 'bar' }, function(err, data) {5269* // if `myFunction` takes < 1000 ms to execute, `err`5270* // and `data` will have their expected values5271*5272* // else `err` will be an Error with the code 'ETIMEDOUT'5273* });5274*/5275function timeout(asyncFn, milliseconds, info) {5276var fn = wrapAsync(asyncFn);52775278return initialParams((args, callback) => {5279var timedOut = false;5280var timer;52815282function timeoutCallback() {5283var name = asyncFn.name || 'anonymous';5284var error = new Error('Callback function "' + name + '" timed out.');5285error.code = 'ETIMEDOUT';5286if (info) {5287error.info = info;5288}5289timedOut = true;5290callback(error);5291}52925293args.push((...cbArgs) => {5294if (!timedOut) {5295callback(...cbArgs);5296clearTimeout(timer);5297}5298});52995300// setup timer and call original function5301timer = setTimeout(timeoutCallback, milliseconds);5302fn(...args);5303});5304}53055306function range(size) {5307var result = Array(size);5308while (size--) {5309result[size] = size;5310}5311return result;5312}53135314/**5315* The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a5316* time.5317*5318* @name timesLimit5319* @static5320* @memberOf module:ControlFlow5321* @method5322* @see [async.times]{@link module:ControlFlow.times}5323* @category Control Flow5324* @param {number} count - The number of times to run the function.5325* @param {number} limit - The maximum number of async operations at a time.5326* @param {AsyncFunction} iteratee - The async function to call `n` times.5327* Invoked with the iteration index and a callback: (n, next).5328* @param {Function} callback - see [async.map]{@link module:Collections.map}.5329* @returns {Promise} a promise, if no callback is provided5330*/5331function timesLimit(count, limit, iteratee, callback) {5332var _iteratee = wrapAsync(iteratee);5333return mapLimit$1(range(count), limit, _iteratee, callback);5334}53355336/**5337* Calls the `iteratee` function `n` times, and accumulates results in the same5338* manner you would use with [map]{@link module:Collections.map}.5339*5340* @name times5341* @static5342* @memberOf module:ControlFlow5343* @method5344* @see [async.map]{@link module:Collections.map}5345* @category Control Flow5346* @param {number} n - The number of times to run the function.5347* @param {AsyncFunction} iteratee - The async function to call `n` times.5348* Invoked with the iteration index and a callback: (n, next).5349* @param {Function} callback - see {@link module:Collections.map}.5350* @returns {Promise} a promise, if no callback is provided5351* @example5352*5353* // Pretend this is some complicated async factory5354* var createUser = function(id, callback) {5355* callback(null, {5356* id: 'user' + id5357* });5358* };5359*5360* // generate 5 users5361* async.times(5, function(n, next) {5362* createUser(n, function(err, user) {5363* next(err, user);5364* });5365* }, function(err, users) {5366* // we should now have 5 users5367* });5368*/5369function times (n, iteratee, callback) {5370return timesLimit(n, Infinity, iteratee, callback)5371}53725373/**5374* The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.5375*5376* @name timesSeries5377* @static5378* @memberOf module:ControlFlow5379* @method5380* @see [async.times]{@link module:ControlFlow.times}5381* @category Control Flow5382* @param {number} n - The number of times to run the function.5383* @param {AsyncFunction} iteratee - The async function to call `n` times.5384* Invoked with the iteration index and a callback: (n, next).5385* @param {Function} callback - see {@link module:Collections.map}.5386* @returns {Promise} a promise, if no callback is provided5387*/5388function timesSeries (n, iteratee, callback) {5389return timesLimit(n, 1, iteratee, callback)5390}53915392/**5393* A relative of `reduce`. Takes an Object or Array, and iterates over each5394* element in parallel, each step potentially mutating an `accumulator` value.5395* The type of the accumulator defaults to the type of collection passed in.5396*5397* @name transform5398* @static5399* @memberOf module:Collections5400* @method5401* @category Collection5402* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.5403* @param {*} [accumulator] - The initial state of the transform. If omitted,5404* it will default to an empty Object or Array, depending on the type of `coll`5405* @param {AsyncFunction} iteratee - A function applied to each item in the5406* collection that potentially modifies the accumulator.5407* Invoked with (accumulator, item, key, callback).5408* @param {Function} [callback] - A callback which is called after all the5409* `iteratee` functions have finished. Result is the transformed accumulator.5410* Invoked with (err, result).5411* @returns {Promise} a promise, if no callback provided5412* @example5413*5414* // file1.txt is a file that is 1000 bytes in size5415* // file2.txt is a file that is 2000 bytes in size5416* // file3.txt is a file that is 3000 bytes in size5417*5418* // helper function that returns human-readable size format from bytes5419* function formatBytes(bytes, decimals = 2) {5420* // implementation not included for brevity5421* return humanReadbleFilesize;5422* }5423*5424* const fileList = ['file1.txt','file2.txt','file3.txt'];5425*5426* // asynchronous function that returns the file size, transformed to human-readable format5427* // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.5428* function transformFileSize(acc, value, key, callback) {5429* fs.stat(value, function(err, stat) {5430* if (err) {5431* return callback(err);5432* }5433* acc[key] = formatBytes(stat.size);5434* callback(null);5435* });5436* }5437*5438* // Using callbacks5439* async.transform(fileList, transformFileSize, function(err, result) {5440* if(err) {5441* console.log(err);5442* } else {5443* console.log(result);5444* // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]5445* }5446* });5447*5448* // Using Promises5449* async.transform(fileList, transformFileSize)5450* .then(result => {5451* console.log(result);5452* // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]5453* }).catch(err => {5454* console.log(err);5455* });5456*5457* // Using async/await5458* (async () => {5459* try {5460* let result = await async.transform(fileList, transformFileSize);5461* console.log(result);5462* // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]5463* }5464* catch (err) {5465* console.log(err);5466* }5467* })();5468*5469* @example5470*5471* // file1.txt is a file that is 1000 bytes in size5472* // file2.txt is a file that is 2000 bytes in size5473* // file3.txt is a file that is 3000 bytes in size5474*5475* // helper function that returns human-readable size format from bytes5476* function formatBytes(bytes, decimals = 2) {5477* // implementation not included for brevity5478* return humanReadbleFilesize;5479* }5480*5481* const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' };5482*5483* // asynchronous function that returns the file size, transformed to human-readable format5484* // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.5485* function transformFileSize(acc, value, key, callback) {5486* fs.stat(value, function(err, stat) {5487* if (err) {5488* return callback(err);5489* }5490* acc[key] = formatBytes(stat.size);5491* callback(null);5492* });5493* }5494*5495* // Using callbacks5496* async.transform(fileMap, transformFileSize, function(err, result) {5497* if(err) {5498* console.log(err);5499* } else {5500* console.log(result);5501* // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }5502* }5503* });5504*5505* // Using Promises5506* async.transform(fileMap, transformFileSize)5507* .then(result => {5508* console.log(result);5509* // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }5510* }).catch(err => {5511* console.log(err);5512* });5513*5514* // Using async/await5515* async () => {5516* try {5517* let result = await async.transform(fileMap, transformFileSize);5518* console.log(result);5519* // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }5520* }5521* catch (err) {5522* console.log(err);5523* }5524* }5525*5526*/5527function transform (coll, accumulator, iteratee, callback) {5528if (arguments.length <= 3 && typeof accumulator === 'function') {5529callback = iteratee;5530iteratee = accumulator;5531accumulator = Array.isArray(coll) ? [] : {};5532}5533callback = once(callback || promiseCallback());5534var _iteratee = wrapAsync(iteratee);55355536eachOf$1(coll, (v, k, cb) => {5537_iteratee(accumulator, v, k, cb);5538}, err => callback(err, accumulator));5539return callback[PROMISE_SYMBOL]5540}55415542/**5543* It runs each task in series but stops whenever any of the functions were5544* successful. If one of the tasks were successful, the `callback` will be5545* passed the result of the successful task. If all tasks fail, the callback5546* will be passed the error and result (if any) of the final attempt.5547*5548* @name tryEach5549* @static5550* @memberOf module:ControlFlow5551* @method5552* @category Control Flow5553* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to5554* run, each function is passed a `callback(err, result)` it must call on5555* completion with an error `err` (which can be `null`) and an optional `result`5556* value.5557* @param {Function} [callback] - An optional callback which is called when one5558* of the tasks has succeeded, or all have failed. It receives the `err` and5559* `result` arguments of the last attempt at completing the `task`. Invoked with5560* (err, results).5561* @returns {Promise} a promise, if no callback is passed5562* @example5563* async.tryEach([5564* function getDataFromFirstWebsite(callback) {5565* // Try getting the data from the first website5566* callback(err, data);5567* },5568* function getDataFromSecondWebsite(callback) {5569* // First website failed,5570* // Try getting the data from the backup website5571* callback(err, data);5572* }5573* ],5574* // optional callback5575* function(err, results) {5576* Now do something with the data.5577* });5578*5579*/5580function tryEach(tasks, callback) {5581var error = null;5582var result;5583return eachSeries$1(tasks, (task, taskCb) => {5584wrapAsync(task)((err, ...args) => {5585if (err === false) return taskCb(err);55865587if (args.length < 2) {5588[result] = args;5589} else {5590result = args;5591}5592error = err;5593taskCb(err ? null : {});5594});5595}, () => callback(error, result));5596}55975598var tryEach$1 = awaitify(tryEach);55995600/**5601* Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,5602* unmemoized form. Handy for testing.5603*5604* @name unmemoize5605* @static5606* @memberOf module:Utils5607* @method5608* @see [async.memoize]{@link module:Utils.memoize}5609* @category Util5610* @param {AsyncFunction} fn - the memoized function5611* @returns {AsyncFunction} a function that calls the original unmemoized function5612*/5613function unmemoize(fn) {5614return (...args) => {5615return (fn.unmemoized || fn)(...args);5616};5617}56185619/**5620* Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when5621* stopped, or an error occurs.5622*5623* @name whilst5624* @static5625* @memberOf module:ControlFlow5626* @method5627* @category Control Flow5628* @param {AsyncFunction} test - asynchronous truth test to perform before each5629* execution of `iteratee`. Invoked with ().5630* @param {AsyncFunction} iteratee - An async function which is called each time5631* `test` passes. Invoked with (callback).5632* @param {Function} [callback] - A callback which is called after the test5633* function has failed and repeated execution of `iteratee` has stopped. `callback`5634* will be passed an error and any arguments passed to the final `iteratee`'s5635* callback. Invoked with (err, [results]);5636* @returns {Promise} a promise, if no callback is passed5637* @example5638*5639* var count = 0;5640* async.whilst(5641* function test(cb) { cb(null, count < 5); },5642* function iter(callback) {5643* count++;5644* setTimeout(function() {5645* callback(null, count);5646* }, 1000);5647* },5648* function (err, n) {5649* // 5 seconds have passed, n = 55650* }5651* );5652*/5653function whilst(test, iteratee, callback) {5654callback = onlyOnce(callback);5655var _fn = wrapAsync(iteratee);5656var _test = wrapAsync(test);5657var results = [];56585659function next(err, ...rest) {5660if (err) return callback(err);5661results = rest;5662if (err === false) return;5663_test(check);5664}56655666function check(err, truth) {5667if (err) return callback(err);5668if (err === false) return;5669if (!truth) return callback(null, ...results);5670_fn(next);5671}56725673return _test(check);5674}5675var whilst$1 = awaitify(whilst, 3);56765677/**5678* Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when5679* stopped, or an error occurs. `callback` will be passed an error and any5680* arguments passed to the final `iteratee`'s callback.5681*5682* The inverse of [whilst]{@link module:ControlFlow.whilst}.5683*5684* @name until5685* @static5686* @memberOf module:ControlFlow5687* @method5688* @see [async.whilst]{@link module:ControlFlow.whilst}5689* @category Control Flow5690* @param {AsyncFunction} test - asynchronous truth test to perform before each5691* execution of `iteratee`. Invoked with (callback).5692* @param {AsyncFunction} iteratee - An async function which is called each time5693* `test` fails. Invoked with (callback).5694* @param {Function} [callback] - A callback which is called after the test5695* function has passed and repeated execution of `iteratee` has stopped. `callback`5696* will be passed an error and any arguments passed to the final `iteratee`'s5697* callback. Invoked with (err, [results]);5698* @returns {Promise} a promise, if a callback is not passed5699*5700* @example5701* const results = []5702* let finished = false5703* async.until(function test(cb) {5704* cb(null, finished)5705* }, function iter(next) {5706* fetchPage(url, (err, body) => {5707* if (err) return next(err)5708* results = results.concat(body.objects)5709* finished = !!body.next5710* next(err)5711* })5712* }, function done (err) {5713* // all pages have been fetched5714* })5715*/5716function until(test, iteratee, callback) {5717const _test = wrapAsync(test);5718return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);5719}57205721/**5722* Runs the `tasks` array of functions in series, each passing their results to5723* the next in the array. However, if any of the `tasks` pass an error to their5724* own callback, the next function is not executed, and the main `callback` is5725* immediately called with the error.5726*5727* @name waterfall5728* @static5729* @memberOf module:ControlFlow5730* @method5731* @category Control Flow5732* @param {Array} tasks - An array of [async functions]{@link AsyncFunction}5733* to run.5734* Each function should complete with any number of `result` values.5735* The `result` values will be passed as arguments, in order, to the next task.5736* @param {Function} [callback] - An optional callback to run once all the5737* functions have completed. This will be passed the results of the last task's5738* callback. Invoked with (err, [results]).5739* @returns undefined5740* @example5741*5742* async.waterfall([5743* function(callback) {5744* callback(null, 'one', 'two');5745* },5746* function(arg1, arg2, callback) {5747* // arg1 now equals 'one' and arg2 now equals 'two'5748* callback(null, 'three');5749* },5750* function(arg1, callback) {5751* // arg1 now equals 'three'5752* callback(null, 'done');5753* }5754* ], function (err, result) {5755* // result now equals 'done'5756* });5757*5758* // Or, with named functions:5759* async.waterfall([5760* myFirstFunction,5761* mySecondFunction,5762* myLastFunction,5763* ], function (err, result) {5764* // result now equals 'done'5765* });5766* function myFirstFunction(callback) {5767* callback(null, 'one', 'two');5768* }5769* function mySecondFunction(arg1, arg2, callback) {5770* // arg1 now equals 'one' and arg2 now equals 'two'5771* callback(null, 'three');5772* }5773* function myLastFunction(arg1, callback) {5774* // arg1 now equals 'three'5775* callback(null, 'done');5776* }5777*/5778function waterfall (tasks, callback) {5779callback = once(callback);5780if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));5781if (!tasks.length) return callback();5782var taskIndex = 0;57835784function nextTask(args) {5785var task = wrapAsync(tasks[taskIndex++]);5786task(...args, onlyOnce(next));5787}57885789function next(err, ...args) {5790if (err === false) return5791if (err || taskIndex === tasks.length) {5792return callback(err, ...args);5793}5794nextTask(args);5795}57965797nextTask([]);5798}57995800var waterfall$1 = awaitify(waterfall);58015802/**5803* An "async function" in the context of Async is an asynchronous function with5804* a variable number of parameters, with the final parameter being a callback.5805* (`function (arg1, arg2, ..., callback) {}`)5806* The final callback is of the form `callback(err, results...)`, which must be5807* called once the function is completed. The callback should be called with a5808* Error as its first argument to signal that an error occurred.5809* Otherwise, if no error occurred, it should be called with `null` as the first5810* argument, and any additional `result` arguments that may apply, to signal5811* successful completion.5812* The callback must be called exactly once, ideally on a later tick of the5813* JavaScript event loop.5814*5815* This type of function is also referred to as a "Node-style async function",5816* or a "continuation passing-style function" (CPS). Most of the methods of this5817* library are themselves CPS/Node-style async functions, or functions that5818* return CPS/Node-style async functions.5819*5820* Wherever we accept a Node-style async function, we also directly accept an5821* [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.5822* In this case, the `async` function will not be passed a final callback5823* argument, and any thrown error will be used as the `err` argument of the5824* implicit callback, and the return value will be used as the `result` value.5825* (i.e. a `rejected` of the returned Promise becomes the `err` callback5826* argument, and a `resolved` value becomes the `result`.)5827*5828* Note, due to JavaScript limitations, we can only detect native `async`5829* functions and not transpilied implementations.5830* Your environment must have `async`/`await` support for this to work.5831* (e.g. Node > v7.6, or a recent version of a modern browser).5832* If you are using `async` functions through a transpiler (e.g. Babel), you5833* must still wrap the function with [asyncify]{@link module:Utils.asyncify},5834* because the `async function` will be compiled to an ordinary function that5835* returns a promise.5836*5837* @typedef {Function} AsyncFunction5838* @static5839*/58405841var index = {5842apply,5843applyEach: applyEach$1,5844applyEachSeries,5845asyncify,5846auto,5847autoInject,5848cargo,5849cargoQueue: cargo$1,5850compose,5851concat: concat$1,5852concatLimit: concatLimit$1,5853concatSeries: concatSeries$1,5854constant,5855detect: detect$1,5856detectLimit: detectLimit$1,5857detectSeries: detectSeries$1,5858dir,5859doUntil,5860doWhilst: doWhilst$1,5861each,5862eachLimit: eachLimit$2,5863eachOf: eachOf$1,5864eachOfLimit: eachOfLimit$2,5865eachOfSeries: eachOfSeries$1,5866eachSeries: eachSeries$1,5867ensureAsync,5868every: every$1,5869everyLimit: everyLimit$1,5870everySeries: everySeries$1,5871filter: filter$1,5872filterLimit: filterLimit$1,5873filterSeries: filterSeries$1,5874forever: forever$1,5875groupBy,5876groupByLimit: groupByLimit$1,5877groupBySeries,5878log,5879map: map$1,5880mapLimit: mapLimit$1,5881mapSeries: mapSeries$1,5882mapValues,5883mapValuesLimit: mapValuesLimit$1,5884mapValuesSeries,5885memoize,5886nextTick,5887parallel,5888parallelLimit,5889priorityQueue,5890queue: queue$1,5891race: race$1,5892reduce: reduce$1,5893reduceRight,5894reflect,5895reflectAll,5896reject: reject$2,5897rejectLimit: rejectLimit$1,5898rejectSeries: rejectSeries$1,5899retry,5900retryable,5901seq,5902series,5903setImmediate: setImmediate$1,5904some: some$1,5905someLimit: someLimit$1,5906someSeries: someSeries$1,5907sortBy: sortBy$1,5908timeout,5909times,5910timesLimit,5911timesSeries,5912transform,5913tryEach: tryEach$1,5914unmemoize,5915until,5916waterfall: waterfall$1,5917whilst: whilst$1,59185919// aliases5920all: every$1,5921allLimit: everyLimit$1,5922allSeries: everySeries$1,5923any: some$1,5924anyLimit: someLimit$1,5925anySeries: someSeries$1,5926find: detect$1,5927findLimit: detectLimit$1,5928findSeries: detectSeries$1,5929flatMap: concat$1,5930flatMapLimit: concatLimit$1,5931flatMapSeries: concatSeries$1,5932forEach: each,5933forEachSeries: eachSeries$1,5934forEachLimit: eachLimit$2,5935forEachOf: eachOf$1,5936forEachOfSeries: eachOfSeries$1,5937forEachOfLimit: eachOfLimit$2,5938inject: reduce$1,5939foldl: reduce$1,5940foldr: reduceRight,5941select: filter$1,5942selectLimit: filterLimit$1,5943selectSeries: filterSeries$1,5944wrapSync: asyncify,5945during: whilst$1,5946doDuring: doWhilst$15947};59485949exports.default = index;5950exports.apply = apply;5951exports.applyEach = applyEach$1;5952exports.applyEachSeries = applyEachSeries;5953exports.asyncify = asyncify;5954exports.auto = auto;5955exports.autoInject = autoInject;5956exports.cargo = cargo;5957exports.cargoQueue = cargo$1;5958exports.compose = compose;5959exports.concat = concat$1;5960exports.concatLimit = concatLimit$1;5961exports.concatSeries = concatSeries$1;5962exports.constant = constant;5963exports.detect = detect$1;5964exports.detectLimit = detectLimit$1;5965exports.detectSeries = detectSeries$1;5966exports.dir = dir;5967exports.doUntil = doUntil;5968exports.doWhilst = doWhilst$1;5969exports.each = each;5970exports.eachLimit = eachLimit$2;5971exports.eachOf = eachOf$1;5972exports.eachOfLimit = eachOfLimit$2;5973exports.eachOfSeries = eachOfSeries$1;5974exports.eachSeries = eachSeries$1;5975exports.ensureAsync = ensureAsync;5976exports.every = every$1;5977exports.everyLimit = everyLimit$1;5978exports.everySeries = everySeries$1;5979exports.filter = filter$1;5980exports.filterLimit = filterLimit$1;5981exports.filterSeries = filterSeries$1;5982exports.forever = forever$1;5983exports.groupBy = groupBy;5984exports.groupByLimit = groupByLimit$1;5985exports.groupBySeries = groupBySeries;5986exports.log = log;5987exports.map = map$1;5988exports.mapLimit = mapLimit$1;5989exports.mapSeries = mapSeries$1;5990exports.mapValues = mapValues;5991exports.mapValuesLimit = mapValuesLimit$1;5992exports.mapValuesSeries = mapValuesSeries;5993exports.memoize = memoize;5994exports.nextTick = nextTick;5995exports.parallel = parallel;5996exports.parallelLimit = parallelLimit;5997exports.priorityQueue = priorityQueue;5998exports.queue = queue$1;5999exports.race = race$1;6000exports.reduce = reduce$1;6001exports.reduceRight = reduceRight;6002exports.reflect = reflect;6003exports.reflectAll = reflectAll;6004exports.reject = reject$2;6005exports.rejectLimit = rejectLimit$1;6006exports.rejectSeries = rejectSeries$1;6007exports.retry = retry;6008exports.retryable = retryable;6009exports.seq = seq;6010exports.series = series;6011exports.setImmediate = setImmediate$1;6012exports.some = some$1;6013exports.someLimit = someLimit$1;6014exports.someSeries = someSeries$1;6015exports.sortBy = sortBy$1;6016exports.timeout = timeout;6017exports.times = times;6018exports.timesLimit = timesLimit;6019exports.timesSeries = timesSeries;6020exports.transform = transform;6021exports.tryEach = tryEach$1;6022exports.unmemoize = unmemoize;6023exports.until = until;6024exports.waterfall = waterfall$1;6025exports.whilst = whilst$1;6026exports.all = every$1;6027exports.allLimit = everyLimit$1;6028exports.allSeries = everySeries$1;6029exports.any = some$1;6030exports.anyLimit = someLimit$1;6031exports.anySeries = someSeries$1;6032exports.find = detect$1;6033exports.findLimit = detectLimit$1;6034exports.findSeries = detectSeries$1;6035exports.flatMap = concat$1;6036exports.flatMapLimit = concatLimit$1;6037exports.flatMapSeries = concatSeries$1;6038exports.forEach = each;6039exports.forEachSeries = eachSeries$1;6040exports.forEachLimit = eachLimit$2;6041exports.forEachOf = eachOf$1;6042exports.forEachOfSeries = eachOfSeries$1;6043exports.forEachOfLimit = eachOfLimit$2;6044exports.inject = reduce$1;6045exports.foldl = reduce$1;6046exports.foldr = reduceRight;6047exports.select = filter$1;6048exports.selectLimit = filterLimit$1;6049exports.selectSeries = filterSeries$1;6050exports.wrapSync = asyncify;6051exports.during = whilst$1;6052exports.doDuring = doWhilst$1;60536054Object.defineProperty(exports, '__esModule', { value: true });60556056})));605760586059