155 lines
5.2 KiB
JavaScript
Raw Normal View History

2025-01-22 16:18:30 +01:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var DEFAULT_MAX = 5;
/**
* Default checker which validates if a next task should begin.
* This can be overwritten to write own checks for example checking the amount
* of used ram and waiting till the ram is low enough for a next task.
*
* It should always resolve with a boolean, either `true` to start a next task
* or `false` to stop executing a new task.
*
* If this method rejects, the error will propagate to the caller
* @param status
* @param tasks
* @returns {Promise}
*/
var defaultNextTaskCheck = function (status, tasks) {
return new Promise(function (resolve, reject) {
resolve(status.amountStarted < tasks.length);
});
};
var DEFAULT_OPTIONS = {
maxInProgress: DEFAULT_MAX,
failFast: false,
nextCheck: defaultNextTaskCheck
};
/**
* Raw throttle function, which can return extra meta data.
* @param tasks required array of tasks to be executed
* @param options Options object
* @returns {Promise}
*/
function raw(tasks, options) {
return new Promise(function (resolve, reject) {
var myOptions = Object.assign({}, DEFAULT_OPTIONS, options);
var result = {
amountDone: 0,
amountStarted: 0,
amountResolved: 0,
amountRejected: 0,
amountNextCheckFalsey: 0,
rejectedIndexes: [],
resolvedIndexes: [],
nextCheckFalseyIndexes: [],
taskResults: []
};
if (tasks.length === 0) {
return resolve(result);
}
var failedFast = false;
var currentTaskIndex = 0;
var executeTask = function (index) {
result.amountStarted++;
if (typeof tasks[index] === 'function') {
tasks[index]().then(function (taskResult) {
result.taskResults[index] = taskResult;
result.resolvedIndexes.push(index);
result.amountResolved++;
taskDone();
}, function (error) {
result.taskResults[index] = error;
result.rejectedIndexes.push(index);
result.amountRejected++;
if (myOptions.failFast === true) {
failedFast = true;
return reject(result);
}
taskDone();
});
}
else {
failedFast = true;
return reject(new Error('tasks[' + index + ']: ' + tasks[index] + ', is supposed to be of type function'));
}
};
var taskDone = function () {
//make sure no more tasks are spawned when we failedFast
if (failedFast === true) {
return;
}
result.amountDone++;
if (typeof myOptions.progressCallback === 'function') {
myOptions.progressCallback(result);
}
if (result.amountDone === tasks.length) {
return resolve(result);
}
if (currentTaskIndex < tasks.length) {
nextTask(currentTaskIndex++);
}
};
var nextTask = function (index) {
//check if we can execute the next task
myOptions.nextCheck(result, tasks).then(function (canExecuteNextTask) {
if (canExecuteNextTask === true) {
//execute it
executeTask(index);
}
else {
result.amountNextCheckFalsey++;
result.nextCheckFalseyIndexes.push(index);
taskDone();
}
}, reject);
};
//spawn the first X task
for (var i = 0; i < Math.min(myOptions.maxInProgress, tasks.length); i++) {
nextTask(currentTaskIndex++);
}
});
}
exports.raw = raw;
/**
* Executes the raw function, but only return the task array
* @param tasks
* @param options
* @returns {Promise}
*/
function executeRaw(tasks, options) {
return new Promise(function (resolve, reject) {
raw(tasks, options).then(function (result) {
resolve(result.taskResults);
}, function (error) {
if (error instanceof Error) {
reject(error);
}
else {
reject(error.taskResults[error.rejectedIndexes[0]]);
}
});
});
}
/**
* Simply run all the promises after each other, so in synchronous manner
* @param tasks required array of tasks to be executed
* @param options Options object
* @returns {Promise}
*/
function sync(tasks, options) {
var myOptions = Object.assign({}, { maxInProgress: 1, failFast: true }, options);
return executeRaw(tasks, myOptions);
}
exports.sync = sync;
/**
* Exposes the same behaviour as Promise.All(), but throttled!
* @param tasks required array of tasks to be executed
* @param options Options object
* @returns {Promise}
*/
function all(tasks, options) {
var myOptions = Object.assign({}, { failFast: true }, options);
return executeRaw(tasks, myOptions);
}
exports.all = all;
//# sourceMappingURL=throttle.js.map