├── .gitignore ├── .npmignore ├── .vscode ├── tasks.json └── launch.json ├── tsconfig.json ├── main.ts ├── LICENSE ├── package.json ├── test.ts ├── index.ts └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.js 3 | *.js.map 4 | *.d.ts 5 | *.log 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | index.ts 2 | *.js.map 3 | test 4 | test.* 5 | main.* 6 | tsconfig.json 7 | .vscode 8 | *.log 9 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "command": "tsc", 4 | "isShellCommand": true, 5 | "showOutput": "silent", 6 | "args": ["-p", "."], 7 | "problemMatcher": "$tsc" 8 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "esnext", 5 | "strict": true, 6 | "removeComments": true, 7 | "preserveConstEnums": false, 8 | "sourceMap": true, 9 | "declaration": true 10 | }, 11 | "files": [ 12 | "index.ts", 13 | "main.ts", 14 | "test.ts" 15 | ] 16 | } -------------------------------------------------------------------------------- /main.ts: -------------------------------------------------------------------------------- 1 | import * as Parallel from './index'; 2 | 3 | (async function () { 4 | var list = [100, 200, 300]; 5 | var start = new Date(); 6 | await Parallel.each(list, async value => { 7 | await Parallel.sleep(value); 8 | console.log('sleep', value); 9 | }); 10 | console.log('done', new Date().getTime() - start.getTime()); 11 | })(); -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceRoot}\\index.js", 12 | "cwd": "${workspaceRoot}", 13 | "outFiles": [], 14 | "sourceMaps": true 15 | }, 16 | { 17 | "type": "node", 18 | "request": "attach", 19 | "name": "Attach to Process", 20 | "port": 5858, 21 | "outFiles": [], 22 | "sourceMaps": true 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Dave Templin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-parallel", 3 | "version": "2.0.0", 4 | "description": "Async enabled each(), map(), filter() functions that work just like their standard counterparts, but can be used with async/await and also provide concurrency limiting. Includes built-in typings and JSDoc comments for IntelliSense documentation.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha", 8 | "start": "node main.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/davetemplin/async-parallel.git" 13 | }, 14 | "keywords": [ 15 | "asynchronous", 16 | "async", 17 | "await", 18 | "await-await", 19 | "await/await", 20 | "concurrent", 21 | "concurrency", 22 | "parallel", 23 | "typescript", 24 | "promise", 25 | "promisify", 26 | "promisified", 27 | "each", 28 | "map", 29 | "invoke", 30 | "foreach", 31 | "filter", 32 | "every", 33 | "reduce", 34 | "some", 35 | "iterative", 36 | "functions" 37 | ], 38 | "author": { 39 | "name": "Dave Templin", 40 | "email": "davetemplin@hotmail.com", 41 | "url": "https://github.com/davetemplin/" 42 | }, 43 | "license": "MIT", 44 | "bugs": { 45 | "url": "https://github.com/davetemplin/async-parallel/issues" 46 | }, 47 | "homepage": "https://github.com/davetemplin/async-parallel#readme", 48 | "devDependencies": { 49 | "@types/chai": "^3.4.34", 50 | "@types/mocha": "^2.2.37", 51 | "@types/node": "^7.0.0", 52 | "chai": "^3.4.1", 53 | "mocha": "^2.3.4" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test.ts: -------------------------------------------------------------------------------- 1 | // Project: https://github.com/davetemplin/async-parallel/ 2 | // Written by: Dave Templin 3 | 4 | import * as Parallel from './index'; 5 | import {sleep} from './index'; 6 | import * as path from 'path'; 7 | import {assert} from 'chai'; 8 | 9 | describe('all', function () { 10 | 11 | describe('Parallel', function () { 12 | 13 | it('pool', async function () { 14 | var n = 0; 15 | var tasks = [ 16 | async function (): Promise { n++; await sleep(10); n--; }, 17 | async function (): Promise { n++; await sleep(11); n--; }, 18 | async function (): Promise { n++; await sleep(12); n--; }, 19 | async function (): Promise { n++; await sleep(13); n--; }, 20 | async function (): Promise { n++; await sleep(12); n--; }, 21 | async function (): Promise { n++; await sleep(11); n--; } 22 | ]; 23 | await Parallel.pool(3, async () => { 24 | var task = tasks.shift(); 25 | if (task) 26 | await task(); 27 | return tasks.length > 0; 28 | }); 29 | assert(tasks.length === 0); 30 | assert(n === 0); 31 | }); 32 | 33 | it('each', async function () { 34 | var list = [10, 20, 30]; 35 | var result = 0; 36 | var start = new Date(); 37 | await Parallel.each(list, async (value) => { 38 | await sleep(value); 39 | result += value; 40 | }); 41 | assert(result === 60); 42 | }); 43 | 44 | it ('invoke', async function () { 45 | var result: number = 0; 46 | await Parallel.invoke([ 47 | async function (): Promise { 48 | await sleep(10); 49 | result += 10; 50 | }, 51 | async function (): Promise { 52 | await sleep(20); 53 | result += 20; 54 | }, 55 | async function (): Promise { 56 | await sleep(30); 57 | result += 30; 58 | } 59 | ]); 60 | assert(result === 60); 61 | }); 62 | 63 | it('map', async function () { 64 | var list = [50, 20, 10, 40]; 65 | var result = await Parallel.map(list, async (value) => { 66 | await sleep(value); 67 | return value / 10; 68 | }); 69 | assert(result.join(',') === '5,2,1,4'); 70 | }); 71 | 72 | it('filter', async function () { 73 | var list = [51, 50, 20, 21, 10, 40, 41]; 74 | var result = await Parallel.filter(list, async (value) => { 75 | await sleep(value); 76 | return value % 10 === 0; 77 | }); 78 | assert(result.join(',') === '50,20,10,40'); 79 | }); 80 | 81 | it('each empty', async function () { 82 | var flag = false; 83 | await Parallel.each([], async () => flag = true); 84 | assert(flag === false); 85 | }); 86 | 87 | it('each null', async function () { 88 | var flag = false; 89 | await Parallel.each(null, async () => flag = true); 90 | assert(flag === false); 91 | }); 92 | 93 | it('each undefined', async function () { 94 | var flag = false; 95 | await Parallel.each(undefined, async () => flag = true); 96 | assert(flag === false); 97 | }); 98 | 99 | }); 100 | }); -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | // Project: https://github.com/davetemplin/async-parallel/ 2 | // Written by: Dave Templin 3 | 4 | /** 5 | * A list of errors resulting from a parallel function. 6 | */ 7 | export class MultiError extends Error { 8 | constructor(public list: Array) { 9 | super(`${list.length} errors`); 10 | } 11 | } 12 | 13 | /** 14 | * Defines the options for a parallel function. 15 | */ 16 | export interface Options { 17 | concurrency: number; 18 | } 19 | 20 | /** 21 | * The current default concurrency setting. 22 | */ 23 | export var concurrency = 0; 24 | 25 | /** 26 | * Sets a default that limits the number of concurrent callback actions for all parallel functions. 27 | * Specifying the concurrency at the function level supercedes this setting. 28 | * @param {string} value Specifies the new default concurrency setting. 29 | */ 30 | export function setConcurrency(value: number): void { 31 | concurrency = value; 32 | } 33 | 34 | /** 35 | * Calls a provided function once per input in parallel. 36 | * @param list A list of input elements to iterate. 37 | * @param action An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. 38 | * @param options Limits the number of callback actions to run concurrently. 39 | */ 40 | export async function each(list: T1[], action: {(value: T1, index: number, list: T1[]): Promise}, options?: Options|number): Promise { 41 | if (list && list.length > 0) { 42 | list = list.slice(0); 43 | var size = resolveOptions(options).concurrency || list.length; 44 | var i = 0; 45 | await pool(size, async () => { 46 | if (list.length > 0) 47 | await action(list.shift()!, i++, list); 48 | return list.length > 0; 49 | }); 50 | } 51 | } 52 | 53 | /** 54 | * Tests whether all elements in the array pass the test implemented by the provided function. 55 | * @param list A list of input elements to test. 56 | * @param action An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to true for elements that pass the test. 57 | * @param options Limits the number of callback actions to run concurrently. 58 | * @returns Returns true if every test resolved to true, otherwise false. 59 | */ 60 | export async function every(list: T[], action: {(value: T, index: number, list: T[]): Promise}, options?: Options|number): Promise { 61 | var result = true; 62 | if (list && list.length > 0) { 63 | list = list.slice(0); 64 | var size = resolveOptions(options).concurrency || list.length; 65 | var i = 0; 66 | await pool(size, async () => { 67 | if (list.length > 0) 68 | if (!await action(list.shift()!, i++, list)) 69 | result = false; 70 | return !result || list.length > 0; 71 | }); 72 | } 73 | return result; 74 | } 75 | 76 | /** 77 | * Creates a new array with all elements that pass the test implemented by the provided function in parallel. 78 | * The output will be in the same order as the input. 79 | * @param list A list of input elements to test. 80 | * @param action An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to true for elements to be included in the output list. 81 | * @param options Limits the number of callback actions to run concurrently. 82 | * @returns A list of filtered elements in the same order as the input. 83 | */ 84 | export async function filter(list: T[], action: {(value: T, index: number, list: T[]): Promise}, options?: Options|number): Promise { 85 | var result: T[] = []; 86 | if (list && list.length > 0) { 87 | var clone = list.slice(0); 88 | var size = resolveOptions(options).concurrency || list.length; 89 | var i = 0; 90 | await pool(size, async () => { 91 | if (clone.length > 0) { 92 | var j = i++; 93 | var value = clone.shift(); 94 | if (await action(value!, i, clone)) 95 | result[j] = value!; 96 | } 97 | return clone.length > 0; 98 | }); 99 | } 100 | return result.filter(value => value !== undefined); 101 | } 102 | 103 | /** 104 | * Calls a set of provided functions in parallel. 105 | * @param list A list of async function callbacks to invoke. The callback takes no arguments and resolves to a void. 106 | * @param options Limits the number of callback actions to run concurrently. 107 | */ 108 | export async function invoke(list: {(): Promise}[], options?: Options|number): Promise { 109 | var result: T[] = []; 110 | if (list && list.length > 0) { 111 | list = list.slice(0); 112 | var size = resolveOptions(options).concurrency || list.length; 113 | var i = 0; 114 | await pool(size, async function (this: any) { 115 | if (list.length > 0) { 116 | var j = i++; 117 | result[j] = await list.shift()!.call(this); 118 | } 119 | return list.length > 0; 120 | }); 121 | } 122 | return result; 123 | } 124 | 125 | /** 126 | * Creates a new array with the results of calling a provided function in parallel on every input. 127 | * The output will be in the same order as the input. 128 | * @param list A list of input elements to map. 129 | * @param action An async function callback that produces an element of the output list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to a single output element. 130 | * @param options Limits the number of callback actions to run concurrently. 131 | * @returns A list of mapped elements in the same order as the input. 132 | */ 133 | export async function map(list: T1[], action: {(value: T1, index: number, list: T1[]): Promise}, options?: Options|number): Promise { 134 | var result: T2[] = []; 135 | if (list && list.length > 0) { 136 | list = list.slice(0); 137 | var size = resolveOptions(options).concurrency || list.length; 138 | var i = 0; 139 | await pool(size, async () => { 140 | if (list.length > 0) { 141 | var j = i++; 142 | result[j] = await action(list.shift()!, j, list); 143 | } 144 | return list.length > 0; 145 | }); 146 | } 147 | return result; 148 | } 149 | 150 | /** 151 | * Repeatedly invokes a provided async function until `false` is returned, after which no new instances will be invoked. 152 | * The overall operation is resolved when all existing instances have been resolved. 153 | * @param size Specifies the size of the pool indicating the number of parallel instances of the provided async function to maintain. 154 | * @param task The provided async function callback that takes no arguments and resolves to a boolean. Return `true` to continue, or `false` when all processing is complete. 155 | */ 156 | export async function pool(size: number, task: {(): Promise}): Promise { 157 | var active = 0; 158 | var done = false; 159 | var errors: Array = []; 160 | return new Promise((resolve, reject) => { 161 | next(); 162 | function next(): void { 163 | while (active < size && !done) { 164 | active += 1; 165 | task() 166 | .then(more => { 167 | if (--active === 0 && (done || !more)) 168 | errors.length === 0 ? resolve() : reject(new MultiError(errors)); 169 | else if (more) 170 | next(); 171 | else 172 | done = true; 173 | }) 174 | .catch(err => { 175 | errors.push(err); 176 | done = true; 177 | if (--active === 0) 178 | reject(new MultiError(errors)); 179 | }); 180 | } 181 | } 182 | }); 183 | } 184 | 185 | /** 186 | * Applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. 187 | * @param list A list of input elements to reduce. 188 | * @param action An async function callback invoked for each element in the list. The callback takes four arguments: the accumulated value previously returned in the last invocation of the callback or initialValue, the current element being processed, the index of the current element, and the input list. The callback resolves to an updated accumulated value. 189 | * @param initialValue Value to use as the first argument to the first call of the callback. 190 | * @param options Limits the number of callback actions to run concurrently. 191 | * @returns The value that results from the reduction. 192 | */ 193 | export async function reduce(list: T1[], action: {(accumulator: T2, value: T1, index: number, list: T1[]): Promise}, value: T2, options?: Options|number): Promise { 194 | var result = value; 195 | if (list && list.length > 0) { 196 | list = list.slice(0); 197 | var size = resolveOptions(options).concurrency || list.length; 198 | var i = 0; 199 | await pool(size, async () => { 200 | if (list.length > 0) 201 | result = await action(result, list.shift()!, i++, list); 202 | return list.length > 0; 203 | }); 204 | } 205 | return result; 206 | } 207 | 208 | /** 209 | * Sleeps for the specified duration. 210 | * @param milliseconds The amount of time to sleep in milliseconds. 211 | */ 212 | export async function sleep(milliseconds: number): Promise { 213 | return new Promise(resolve => 214 | setTimeout(() => 215 | resolve(), milliseconds)); 216 | } 217 | 218 | /** 219 | * Tests whether some element in the array passes the test implemented by the provided function. 220 | * @param list A list of input elements to test. 221 | * @param action An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to true for elements that pass the test. 222 | * @param options Limits the number of callback actions to run concurrently. 223 | * @returns Returns true if some (at least one) test resolved to true, otherwise false. 224 | */ 225 | export async function some(list: T[], action: {(value: T, index: number, list: T[]): Promise}, options?: Options|number): Promise { 226 | var result = false; 227 | if (list && list.length > 0) { 228 | list = list.slice(0); 229 | var size = resolveOptions(options).concurrency || list.length; 230 | var i = 0; 231 | await pool(size, async () => { 232 | if (list.length > 0) 233 | if (await action(list.shift()!, i++, list)) 234 | result = true; 235 | return result || list.length > 0; 236 | }); 237 | } 238 | return result; 239 | } 240 | 241 | function resolveOptions(value?: Options|number): Options { 242 | if (typeof value === 'number') 243 | return {concurrency: value}; 244 | else if (typeof value === 'object') 245 | return Object.assign({concurrency: concurrency}, value); 246 | else 247 | return {concurrency: concurrency}; 248 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # async-parallel 2 | Async enabled each(), map(), filter() functions that work just like their standard counterparts, but can be used with async/await and also provide concurrency limiting. Includes built-in typings and JSDoc comments for IntelliSense documentation. 3 | 4 | The following iterative functions are provided: 5 | 6 | * **Parallel.each** calls a provided function once per input in parallel. 7 | * **Parallel.map** creates a new array with the results of calling a provided function in parallel on every input, the output will be in the same order as the input. 8 | * **Parallel.filter** creates a new array with all elements that pass the test implemented by the provided function in parallel, the output will be in the same order as the input. 9 | * **Parallel.every** tests whether all elements in the array pass the test implemented by the provided function. 10 | * **Parallel.reduce** applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. 11 | * **Parallel.some** tests whether some element in the array passes the test implemented by the provided function. 12 | 13 | Every function above provides a `concurrency` parameter to limit the maximum number of parallel instances at the function call level. In addition, concurrency can be limited at a global level with the following function: 14 | 15 | * **Parallel.setConcurrency** sets a default that limits the number of concurrent actions for all parallel functions. Superceded by the `concurrency` parameter at the function-call level. 16 | 17 | The following additional utility functions are also provided: 18 | 19 | * **Parallel.invoke** calls a set of provided functions in parallel. 20 | * **Parallel.pool** maintains a pool of parallel instances of a provided function until `false` is returned. 21 | * **Parallel.sleep** sleeps for the specified duration. 22 | 23 | ## Parallel.each example 24 | ```js 25 | var list = [100, 200, 300]; // provide list of inputs here 26 | await Parallel.each(list, async item => { 27 | // process each item here 28 | }); 29 | ``` 30 | 31 | ## Parallel.map example 32 | ```js 33 | var list = [100, 200, 300]; // provide list of inputs here 34 | var result = await Parallel.map(list, async item => { 35 | // process each item here 36 | }); 37 | // result available here 38 | ``` 39 | 40 | ## Parallel.filter example 41 | ```js 42 | var list = [100, 200, 300]; // provide list of inputs here 43 | var result = await Parallel.filter(list, async item => { 44 | // test each item here returning true to include or false to reject 45 | }); 46 | // result available here 47 | ``` 48 | 49 | ## Parallel.invoke example 50 | ```js 51 | await Parallel.invoke([ 52 | async () => { /* task #1 here */ }, 53 | async () => { /* task #2 here */ }, 54 | async () => { /* task #3 here */ }, 55 | async () => { /* task #4 here */ }, 56 | async () => { /* task #5 here */ } 57 | ], 2); 58 | ``` 59 | > Note: The same result can be achieved without a library using `Promise.all`, however `Parallel.invoke` provides an ability to limit the concurrency. 60 | Therefore, in the example above only 2 of the tasks will be run at the same time. 61 | 62 | 63 | ## Getting Started 64 | 65 | Make sure you're running Node v4 or higher and TypeScript 1.8 or higher... 66 | ``` 67 | $ node -v 68 | v7.3.3 69 | $ npm install -g typescript 70 | $ tsc -v 71 | Version 2.3.4 72 | ``` 73 | 74 | Install package... 75 | ``` 76 | $ npm install async-parallel 77 | ``` 78 | 79 | Write some code... 80 | ```js 81 | import * as Parallel from 'async-parallel'; 82 | (async function () { 83 | var list = [100, 200, 300]; 84 | var start = new Date(); 85 | await Parallel.each(list, async value => { 86 | await Parallel.sleep(value); 87 | console.log('sleep', value); 88 | }); 89 | console.log('done', new Date().getTime() - start.getTime()); 90 | })(); 91 | ``` 92 | 93 | Save the above to a file `index.ts`, build and run it! 94 | ``` 95 | $ tsc index.ts --target es6 --module commonjs 96 | $ node index.js 97 | sleep 100 98 | sleep 200 99 | sleep 300 100 | done 303 101 | ``` 102 | 103 | ## Concurrency 104 | The number of concurrent actions can be limited at the function level, or by calling the `Parallel.setConcurrency()` which sets a default concurrency setting. 105 | 106 | * concurrency=0 specifies an unlimited number of actions (this is the default). 107 | * concurrency=1 causes all actions to be performed in series, or one-at-a-time (also useful for debugging/troubleshooting). 108 | * concurrency>1 limits concurrency such that no more than the specified number of actions will be run at the same time. 109 | 110 | Examples: 111 | ```js 112 | await Parallel.each([100, 200, 300], async item => { 113 | // process each item here 114 | }, 2); // process no more than 2 items at the same time 115 | ``` 116 | 117 | ```js 118 | await Parallel.invoke([ 119 | async () => { /* task #1 here */ }, 120 | async () => { /* task #2 here */ }, 121 | async () => { /* task #3 here */ }, 122 | async () => { /* task #4 here */ }, 123 | async () => { /* task #5 here */ } 124 | ], 3); // process no more than 3 items at the same time 125 | ``` 126 | 127 | ```js 128 | Parallel.setConcurrency(10); // no more than 10 actions running at the same time by default 129 | ``` 130 | 131 | ## Errors 132 | If one or more actions fail then no further actions will be started and a rollup error will result after all pending actions are complete. 133 | The rollup error will contain a list of individual failures as shown below. 134 | 135 | ```js 136 | try { 137 | await Parallel.pool(2, async () => 138 | await someRecurringTask()); 139 | } 140 | catch (err) { 141 | console.log(err.message); // print the rollup error message 142 | for (var item of err.list) 143 | console.log(item.message); // print each specific error message 144 | } 145 | ``` 146 | 147 | ## Parallel.pool example 148 | Create several actions, running no more than 2 at a time. 149 | 150 | ```js 151 | var actions = [ 152 | async function () { /* task #1 here */ }, 153 | async function () { /* task #2 here */ }, 154 | async function () { /* task #3 here */ }, 155 | async function () { /* task #4 here */ }, 156 | async function () { /* task #5 here */ } 157 | ]; 158 | await Parallel.pool(2, async () => { 159 | var action = actions.shift(); 160 | await action(); 161 | return action.length > 0; 162 | }); 163 | // all actions are complete here 164 | ``` 165 | 166 | # Reference 167 | 168 | 169 | ## each 170 | 171 | Calls a provided function once per input in parallel. 172 | 173 | `each(list: T1[], action: {(value: T1, index: number, list: T1[]): Promise}, concurrency?: number): Promise` 174 | 175 | | Parameter | Type | Description | 176 | | ----------- | -------------- | --------------------------------------------------------------------------- | 177 | | list | (generic) | A list of input elements to iterate. | 178 | | action | function | An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. | 179 | | concurrency | number | Limits the number of callback actions to run concurrently. | 180 | 181 | 182 | ## every 183 | 184 | Tests whether all elements in the array pass the test implemented by the provided function. 185 | 186 | `every(list: T[], action: {(value: T, index: number, list: T[]): Promise}, concurrency?: number): Promise` 187 | 188 | | Parameter | Type | Description | 189 | | ---------- | --------------- | --------------------------------------------------------------------------- | 190 | | list | (generic) | A list of input elements to test. | 191 | | action | function | An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to true for elements that pass the test. | 192 | | concurrency | number | Limits the number of callback actions to run concurrently. | 193 | 194 | Returns true if every test resolved to true, otherwise false. 195 | 196 | ## filter 197 | 198 | Creates a new array with all elements that pass the test implemented by the provided function in parallel. 199 | 200 | `filter(list: T[], action: {(value: T, index: number, list: T[]): Promise}, concurrency?: number): Promise` 201 | 202 | | Parameter | Type | Description | 203 | | ---------- | --------------- | --------------------------------------------------------------------------- | 204 | | list | (generic) | A list of input elements to test. | 205 | | action | function | An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to true for elements to be included in the output list. | 206 | | concurrency | number | Limits the number of callback actions to run concurrently. | 207 | 208 | Returns a list of filtered elements in the same order as the input. 209 | 210 | ## invoke 211 | 212 | Calls a set of provided functions in parallel. 213 | 214 | `invoke(list: {(): Promise}[], concurrency?: number): Promise` 215 | 216 | | Parameter | Type | Description | 217 | | ----------- | --------------- | --------------------------------------------------------------------------- | 218 | | list | function[] | A list of async function callbacks to invoke. The callback takes no arguments and resolves to a void. | 219 | | concurrency | number | Limits the number of callback actions to run concurrently. | 220 | 221 | 222 | ## map 223 | 224 | Creates a new array with the results of calling a provided function in parallel on every input. 225 | The output will be in the same order as the input. 226 | 227 | `map(list: T1[], action: {(value: T1, index: number, list: T1[]): Promise}, concurrency?: number): Promise` 228 | 229 | | Parameter | Type | Description | 230 | | ----------- | --------------- | --------------------------------------------------------------------------- | 231 | | list | (generic) | A list of input elements to map. | 232 | | action | function | An async function callback that produces an element of the output list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to a single output element. | 233 | | concurrency | number | Limits the number of callback actions to run concurrently. | 234 | 235 | Returns a list of mapped elements in the same order as the input. 236 | 237 | 238 | ## pool 239 | 240 | Repeatedly invokes a provided async function until `false` is returned, after which no new instances will be invoked. 241 | The function should return a boolean result where `true` indicates **more** iterations should be performed, and `false` indicates that no more iterations should be performed. 242 | 243 | `pool(size: number, task: {(): Promise}): Promise` 244 | 245 | | Parameter | Type | Description | 246 | | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | 247 | | size | number | Specifies the size of the pool indicating the number of parallel instances of the provided async function to maintain. | 248 | | task | function | The provided async function callback that takes no arguments and resolves to a boolean. Return `true` to continue, or `false` when all processing is complete. | 249 | 250 | 251 | ## reduce 252 | 253 | Applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. 254 | 255 | `reduce(list: T1[], action: {(accumulator: T2, value: T1, index: number, list: T1[]): Promise}, value: T2, concurrency?: number): Promise` 256 | 257 | | Parameter | Type | Description | 258 | | ------------ | --------- | --------------------------------------------------------------------------- | 259 | | list | (generic) | A list of input elements to reduce. | 260 | | action | function | An async function callback invoked for each element in the list. The callback takes four arguments: the accumulated value previously returned in the last invocation of the callback or initialValue, the current element being processed, the index of the current element, and the input list. The callback resolves to an updated accumulated value. | 261 | | initialValue | (generic) | Value to use as the first argument to the first call of the callback. | 262 | | concurrency | number | Limits the number of callback actions to run concurrently. | 263 | 264 | Returns the value that results from the reduction. 265 | 266 | 267 | ## setConcurrency 268 | 269 | Sets a default that limits the number of concurrent callback actions for all parallel functions. 270 | Specifying the concurrency at the function level supercedes this setting. 271 | 272 | `setConcurrency(value: number): void` 273 | 274 | | Parameter | Type | Description | 275 | | ---------- | --------------- | --------------------------------------------------------------------------- | 276 | | value | number | Specifies the new default concurrency setting. | 277 | 278 | 279 | ## sleep 280 | 281 | Sleeps for the specified duration. 282 | 283 | `sleep(milliseconds: number): Promise` 284 | 285 | | Parameter | Type | Description | 286 | | ------------ | ------------- | --------------------------------------------------------------------------- | 287 | | milliseconds | number | The amount of time to sleep in milliseconds. | 288 | 289 | 290 | ## some 291 | 292 | Tests whether some element in the array passes the test implemented by the provided function. 293 | 294 | `some(list: T[], action: {(value: T, index: number, list: T[]): Promise}, concurrency?: number): Promise` 295 | 296 | | Parameter | Type | Description | 297 | | ----------- | -------------- | --------------------------------------------------------------------------- | 298 | | list | (generic) | A list of input elements to test. | 299 | | action | function | An async function callback invoked for each element in the list. The callback takes three arguments: the current element being processed, the index of the current element, and the input list. The callback resolves to true for elements that pass the test. | 300 | | concurrency | number | Limits the number of callback actions to run concurrently. | 301 | 302 | Returns true if some (at least one) test resolved to true, otherwise false. --------------------------------------------------------------------------------