CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes45downloads
auto.js333 linesDownload Raw Back to async
1'use strict';2 3Object.defineProperty(exports, "__esModule", {4    value: true5});6exports.default = auto;7 8var _once = require('./internal/once.js');9 10var _once2 = _interopRequireDefault(_once);11 12var _onlyOnce = require('./internal/onlyOnce.js');13 14var _onlyOnce2 = _interopRequireDefault(_onlyOnce);15 16var _wrapAsync = require('./internal/wrapAsync.js');17 18var _wrapAsync2 = _interopRequireDefault(_wrapAsync);19 20var _promiseCallback = require('./internal/promiseCallback.js');21 22function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }23 24/**25 * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on26 * their requirements. Each function can optionally depend on other functions27 * being completed first, and each function is run as soon as its requirements28 * are satisfied.29 *30 * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence31 * will stop. Further tasks will not execute (so any other functions depending32 * on it will not run), and the main `callback` is immediately called with the33 * error.34 *35 * {@link AsyncFunction}s also receive an object containing the results of functions which36 * have completed so far as the first argument, if they have dependencies. If a37 * task function has no dependencies, it will only be passed a callback.38 *39 * @name auto40 * @static41 * @memberOf module:ControlFlow42 * @method43 * @category Control Flow44 * @param {Object} tasks - An object. Each of its properties is either a45 * function or an array of requirements, with the {@link AsyncFunction} itself the last item46 * in the array. The object's key of a property serves as the name of the task47 * defined by that property, i.e. can be used when specifying requirements for48 * other tasks. The function receives one or two arguments:49 * * a `results` object, containing the results of the previously executed50 *   functions, only passed if the task has any dependencies,51 * * a `callback(err, result)` function, which must be called when finished,52 *   passing an `error` (which can be `null`) and the result of the function's53 *   execution.54 * @param {number} [concurrency=Infinity] - An optional `integer` for55 * determining the maximum number of tasks that can be run in parallel. By56 * default, as many as possible.57 * @param {Function} [callback] - An optional callback which is called when all58 * the tasks have been completed. It receives the `err` argument if any `tasks`59 * pass an error to their callback. Results are always returned; however, if an60 * error occurs, no further `tasks` will be performed, and the results object61 * will only contain partial results. Invoked with (err, results).62 * @returns {Promise} a promise, if a callback is not passed63 * @example64 *65 * //Using Callbacks66 * async.auto({67 *     get_data: function(callback) {68 *         // async code to get some data69 *         callback(null, 'data', 'converted to array');70 *     },71 *     make_folder: function(callback) {72 *         // async code to create a directory to store a file in73 *         // this is run at the same time as getting the data74 *         callback(null, 'folder');75 *     },76 *     write_file: ['get_data', 'make_folder', function(results, callback) {77 *         // once there is some data and the directory exists,78 *         // write the data to a file in the directory79 *         callback(null, 'filename');80 *     }],81 *     email_link: ['write_file', function(results, callback) {82 *         // once the file is written let's email a link to it...83 *         callback(null, {'file':results.write_file, 'email':'user@example.com'});84 *     }]85 * }, function(err, results) {86 *     if (err) {87 *         console.log('err = ', err);88 *     }89 *     console.log('results = ', results);90 *     // results = {91 *     //     get_data: ['data', 'converted to array']92 *     //     make_folder; 'folder',93 *     //     write_file: 'filename'94 *     //     email_link: { file: 'filename', email: 'user@example.com' }95 *     // }96 * });97 *98 * //Using Promises99 * async.auto({100 *     get_data: function(callback) {101 *         console.log('in get_data');102 *         // async code to get some data103 *         callback(null, 'data', 'converted to array');104 *     },105 *     make_folder: function(callback) {106 *         console.log('in make_folder');107 *         // async code to create a directory to store a file in108 *         // this is run at the same time as getting the data109 *         callback(null, 'folder');110 *     },111 *     write_file: ['get_data', 'make_folder', function(results, callback) {112 *         // once there is some data and the directory exists,113 *         // write the data to a file in the directory114 *         callback(null, 'filename');115 *     }],116 *     email_link: ['write_file', function(results, callback) {117 *         // once the file is written let's email a link to it...118 *         callback(null, {'file':results.write_file, 'email':'user@example.com'});119 *     }]120 * }).then(results => {121 *     console.log('results = ', results);122 *     // results = {123 *     //     get_data: ['data', 'converted to array']124 *     //     make_folder; 'folder',125 *     //     write_file: 'filename'126 *     //     email_link: { file: 'filename', email: 'user@example.com' }127 *     // }128 * }).catch(err => {129 *     console.log('err = ', err);130 * });131 *132 * //Using async/await133 * async () => {134 *     try {135 *         let results = await async.auto({136 *             get_data: function(callback) {137 *                 // async code to get some data138 *                 callback(null, 'data', 'converted to array');139 *             },140 *             make_folder: function(callback) {141 *                 // async code to create a directory to store a file in142 *                 // this is run at the same time as getting the data143 *                 callback(null, 'folder');144 *             },145 *             write_file: ['get_data', 'make_folder', function(results, callback) {146 *                 // once there is some data and the directory exists,147 *                 // write the data to a file in the directory148 *                 callback(null, 'filename');149 *             }],150 *             email_link: ['write_file', function(results, callback) {151 *                 // once the file is written let's email a link to it...152 *                 callback(null, {'file':results.write_file, 'email':'user@example.com'});153 *             }]154 *         });155 *         console.log('results = ', results);156 *         // results = {157 *         //     get_data: ['data', 'converted to array']158 *         //     make_folder; 'folder',159 *         //     write_file: 'filename'160 *         //     email_link: { file: 'filename', email: 'user@example.com' }161 *         // }162 *     }163 *     catch (err) {164 *         console.log(err);165 *     }166 * }167 *168 */169function auto(tasks, concurrency, callback) {170    if (typeof concurrency !== 'number') {171        // concurrency is optional, shift the args.172        callback = concurrency;173        concurrency = null;174    }175    callback = (0, _once2.default)(callback || (0, _promiseCallback.promiseCallback)());176    var numTasks = Object.keys(tasks).length;177    if (!numTasks) {178        return callback(null);179    }180    if (!concurrency) {181        concurrency = numTasks;182    }183 184    var results = {};185    var runningTasks = 0;186    var canceled = false;187    var hasError = false;188 189    var listeners = Object.create(null);190 191    var readyTasks = [];192 193    // for cycle detection:194    var readyToCheck = []; // tasks that have been identified as reachable195    // without the possibility of returning to an ancestor task196    var uncheckedDependencies = {};197 198    Object.keys(tasks).forEach(key => {199        var task = tasks[key];200        if (!Array.isArray(task)) {201            // no dependencies202            enqueueTask(key, [task]);203            readyToCheck.push(key);204            return;205        }206 207        var dependencies = task.slice(0, task.length - 1);208        var remainingDependencies = dependencies.length;209        if (remainingDependencies === 0) {210            enqueueTask(key, task);211            readyToCheck.push(key);212            return;213        }214        uncheckedDependencies[key] = remainingDependencies;215 216        dependencies.forEach(dependencyName => {217            if (!tasks[dependencyName]) {218                throw new Error('async.auto task `' + key + '` has a non-existent dependency `' + dependencyName + '` in ' + dependencies.join(', '));219            }220            addListener(dependencyName, () => {221                remainingDependencies--;222                if (remainingDependencies === 0) {223                    enqueueTask(key, task);224                }225            });226        });227    });228 229    checkForDeadlocks();230    processQueue();231 232    function enqueueTask(key, task) {233        readyTasks.push(() => runTask(key, task));234    }235 236    function processQueue() {237        if (canceled) return;238        if (readyTasks.length === 0 && runningTasks === 0) {239            return callback(null, results);240        }241        while (readyTasks.length && runningTasks < concurrency) {242            var run = readyTasks.shift();243            run();244        }245    }246 247    function addListener(taskName, fn) {248        var taskListeners = listeners[taskName];249        if (!taskListeners) {250            taskListeners = listeners[taskName] = [];251        }252 253        taskListeners.push(fn);254    }255 256    function taskComplete(taskName) {257        var taskListeners = listeners[taskName] || [];258        taskListeners.forEach(fn => fn());259        processQueue();260    }261 262    function runTask(key, task) {263        if (hasError) return;264 265        var taskCallback = (0, _onlyOnce2.default)((err, ...result) => {266            runningTasks--;267            if (err === false) {268                canceled = true;269                return;270            }271            if (result.length < 2) {272                [result] = result;273            }274            if (err) {275                var safeResults = {};276                Object.keys(results).forEach(rkey => {277                    safeResults[rkey] = results[rkey];278                });279                safeResults[key] = result;280                hasError = true;281                listeners = Object.create(null);282                if (canceled) return;283                callback(err, safeResults);284            } else {285                results[key] = result;286                taskComplete(key);287            }288        });289 290        runningTasks++;291        var taskFn = (0, _wrapAsync2.default)(task[task.length - 1]);292        if (task.length > 1) {293            taskFn(results, taskCallback);294        } else {295            taskFn(taskCallback);296        }297    }298 299    function checkForDeadlocks() {300        // Kahn's algorithm301        // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm302        // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html303        var currentTask;304        var counter = 0;305        while (readyToCheck.length) {306            currentTask = readyToCheck.pop();307            counter++;308            getDependents(currentTask).forEach(dependent => {309                if (--uncheckedDependencies[dependent] === 0) {310                    readyToCheck.push(dependent);311                }312            });313        }314 315        if (counter !== numTasks) {316            throw new Error('async.auto cannot execute tasks due to a recursive dependency');317        }318    }319 320    function getDependents(taskName) {321        var result = [];322        Object.keys(tasks).forEach(key => {323            const task = tasks[key];324            if (Array.isArray(task) && task.indexOf(taskName) >= 0) {325                result.push(key);326            }327        });328        return result;329    }330 331    return callback[_promiseCallback.PROMISE_SYMBOL];332}333module.exports = exports.default;
basant307/AI_Governance_Project · CoolFace