forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			155 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			155 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | "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
 |