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
 |