forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			121 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			121 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | # Promise-parallel-throttle
 | ||
|  | [](https://travis-ci.org/DJWassink/Promise-parallel-throttle) | ||
|  | 
 | ||
|  | Run a array of Promises in parallel. Kinda like Promise.all(), but throttled! | ||
|  | 
 | ||
|  | ## Install 
 | ||
|  | 
 | ||
|  | ### NPM
 | ||
|  | ```bash | ||
|  | npm i promise-parallel-throttle -S | ||
|  | ``` | ||
|  | 
 | ||
|  | ### Yarn
 | ||
|  | ```bash | ||
|  | yarn add promise-parallel-throttle | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Usage
 | ||
|  | 
 | ||
|  | ```js | ||
|  | import Throttle from 'promise-parallel-throttle'; | ||
|  | 
 | ||
|  | //Function which should return a Promise | ||
|  | const doReq = async (firstName, lastName) => { | ||
|  |     //Do something async. | ||
|  |     return firstName + " " + lastName; | ||
|  | } | ||
|  | 
 | ||
|  | const users = [ | ||
|  |     {firstName: "Irene", lastName: "Pullman"}, | ||
|  |     {firstName: "Sean",  lastName: "Parr"} | ||
|  | ]; | ||
|  | 
 | ||
|  | //Queue with functions to be run | ||
|  | const queue = users.map(user => () => doReq(user.firstName, user.lastName)); | ||
|  | 
 | ||
|  | //Default Throttle runs with 5 promises parallel. | ||
|  | const formattedNames = await Throttle.all(queue); | ||
|  | 
 | ||
|  | console.log(formattedNames); //['Irene Pullman', 'Sean Parr'] | ||
|  | ``` | ||
|  | 
 | ||
|  | ## API
 | ||
|  | ### Throttle.all
 | ||
|  | `Throttle.all(tasks, options)` | ||
|  | 
 | ||
|  | Throttle.all is made to behave exactly like Promise.all but instead of all the tasks running in parallel it runs a maxium amount of tasks in parallel. | ||
|  | Only the tasks parameter is required while the [options](#options-object) parameter is optional. | ||
|  | 
 | ||
|  | ### Throttle.sync
 | ||
|  | `Throttle.sync(tasks, options)` | ||
|  | 
 | ||
|  | Throttle.sync runs all the tasks synchronously.  | ||
|  | Once again the tasks array is required, the [options](#options-object) are optional.  | ||
|  | Be aware that this method is simply a wrapper to pass `maxInProgress` with 1. So overwriting this option in the options object would run the tasks again in parallel. | ||
|  | 
 | ||
|  | ### Throttle.raw
 | ||
|  | `Throttle.raw(tasks, options)` | ||
|  |   | ||
|  |  The raw method instead of returning the tasks their results, will return a [result](#result-object--progress-callback) object.  | ||
|  |  Useful if you wan't more statistics about the execution of your tasks. Once again the tasks are required while the [options](#options-object) are optional. | ||
|  | 
 | ||
|  | #### Option's Object
 | ||
|  | |Parameter|Type|Default|Definition| | ||
|  | |:---|:---|:---|:---| | ||
|  | |maxInProgress |Integer|5| max amount of parallel threads| | ||
|  | |failFast |Boolean|true (false for the [raw](#throttleraw) method)| reject after a single error, or keep running| | ||
|  | |progressCallback |Function|Optional| callback with progress reports| | ||
|  | |nextCheck |Function|Optional| function which should return a promise, if the promise resolved true the next task is spawn, errors will propagate and should be handled in the calling code| | ||
|  | 
 | ||
|  | #### Result object / Progress callback
 | ||
|  | The `progressCallback` and the `Raw` will return a `Result` object with the following properties: | ||
|  | 
 | ||
|  | |Property|Type|Start value|Definition| | ||
|  | |:---|:---|:---|:---| | ||
|  | |amountDone|Integer|0|amount of tasks which are finished| | ||
|  | |amountStarted|Integer|0|amount of tasks which started| | ||
|  | |amountResolved|Integer|0|amount of tasks which successfully resolved| | ||
|  | |amountRejected|Integer|0|amount of tasks which returned in an error and are aborted| | ||
|  | |amountNextCheckFalsey|Integer|0|amount of tasks which got a falsey value in the [nextCheck](#nextcheck)| | ||
|  | |rejectedIndexes|Array|[]|all the indexes in the tasks array where the promise rejected| | ||
|  | |resolvedIndexes|Array|[]|all the indexes in the tasks array where the promise resolved| | ||
|  | |nextCheckFalseyIndexes|Array|[]|all the indexes in the tasks array where the [nextCheck](#nextcheck) returned a falsey value| | ||
|  | |taskResults|Array|[]|array containing the result of every task| | ||
|  | 
 | ||
|  | #### nextCheck
 | ||
|  | All the `Throttle` methods have a `nextCheck` method which will be used to verify if a next task is allowed to start.  | ||
|  | 
 | ||
|  | The default `nextCheck` is defined like this; | ||
|  | ```js | ||
|  | const defaultNextTaskCheck = (status, tasks) => { | ||
|  |     return new Promise((resolve, reject) => { | ||
|  |         resolve(status.amountStarted < tasks.length); | ||
|  |     }); | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | This function will get a status object as parameter which adheres to the [Result object](#result-object--progress-callback) and it also receives the list of tasks. | ||
|  | In the default `nextCheck` we simply check if the amount of started exceeds the amount to be done, if not we are free to start an other task. | ||
|  | 
 | ||
|  | This function can be useful to write your own scheduler based on, for example ram/cpu usage. | ||
|  | Lets say that your tasks use a lot of ram and you don't want to exceed a certain amount. | ||
|  | You could then write logic inside a `nextCheck` function which resolves after there is enough ram available to start the next task. | ||
|  | 
 | ||
|  | If a custom implementation decides to reject, the error is propagated and should be handled in the user it's code. If a custom implementation returns a falsey value the task will simply not execute and the next task will be scheduled. | ||
|  | 
 | ||
|  | ## Example
 | ||
|  | Check out the example's directory, it's heavily documented so it should be easy to follow. | ||
|  | 
 | ||
|  | To run the example, at least Node 8.x.x is required, since it supports native async/await. | ||
|  | 
 | ||
|  | Simply run the example with npm: | ||
|  | ``` | ||
|  | npm run-script names | ||
|  | ``` | ||
|  | 
 | ||
|  | Or with Yarn: | ||
|  | ``` | ||
|  | yarn names | ||
|  | ``` |