@particle/async-utils
v4.0.2
Published
Collection of promise-based async utility functions
Downloads
1,315
Maintainers
Keywords
Readme
@particle/async-utils
Collection of promise-based async utility functions.
Installation
npm install @particle/async-utils --save
const asyncUtils = require('@particle/async-utils');
const {
delay,
delayForAtLeast,
timeout,
TimeoutError,
retry,
retryWithBackoff,
asyncFilter,
asyncMap,
asyncReduceSeries,
asyncMapSeries,
execAsPromise,
upon,
isPromise
} = asyncUtils;
API
@particle/async-utils
- @particle/async-utils
- .TimeoutError ⇐ Error
- .delay(ms, [value]) ⇒ Promise.<(undefined|Value)>
- .delayForAtLeast(ms, promise) ⇒ Promise.<*>
- .timeout(promise, ms, [Err]) ⇒ Promise.<*>
- .retry(fn, [options]) ⇒ Promise.<*>
- .retryWithBackoff(fn, [options]) ⇒ Promise.<*>
- .asyncFilter(array, filter, [concurrency]) ⇒ Promise.<(array|Error)>
- .asyncMap(array, fn, [concurrency]) ⇒ Promise.<(array|Error)>
- .asyncReduceSeries(array, fn, [initial]) ⇒ Promise.<(value|Error)>
- .asyncMapSeries(array, fn) ⇒ Promise.<(array|Error)>
- .execAsPromise(fn, ...args) ⇒ Promise.<*>
- .upon(promise) ⇒ Promise.<Array.<{error: Error, value: *}>>
- .isPromise(x) ⇒ boolean
asyncUtils.TimeoutError ⇐ Error
Kind: static class of @particle/async-utils
Extends: Error
Properties
| Name | Type | Default | Description | | --- | --- | --- | --- | | [msg] | string | "The operation timed out" | The error message |
asyncUtils.delay(ms, [value]) ⇒ Promise.<(undefined|Value)>
Create a promise which resolves after a given delay
Kind: static method of @particle/async-utils
Returns: Promise.<(undefined|Value)> - A resolved promise
| Param | Type | Description | | --- | --- | --- | | ms | number | Duration of delay in milliseconds | | [value] | * | Value to resolve the returned promise with (optional) |
Example
delay(10).then(() => 'done!');
const value = await delay(10, 'done!');
asyncUtils.delayForAtLeast(ms, promise) ⇒ Promise.<*>
Enforce a minimum delay for any async function
Kind: static method of @particle/async-utils
Returns: Promise.<*> - The result of your async function
| Param | Type | Description | | --- | --- | --- | | ms | number | Duration of delay in milliseconds | | promise | Promise.<*> | Promise generated by your async function |
Example
let value;
try {
value = await delayForAtLeast(200, myFn());
value // whatever `myFn()` resolved with
} catch (error){
error // whatever `myFn()` rejected with
}
asyncUtils.timeout(promise, ms, [Err]) ⇒ Promise.<*>
Enforce a timeout for any asnyc function
Kind: static method of @particle/async-utils
Returns: Promise.<*> - The result of your async function or a timeout error rejection
| Param | Type | Description | | --- | --- | --- | | promise | Promise.<*> | Promise generated by your async function | | ms | number | Duration of timeout window in milliseconds | | [Err] | string | function | custom error message or type (optional) |
Example
let value;
try {
value = await timeout(myFn(), 1000);
} catch (error){
error.message; // 'The operation timed out'
error instanceof asyncUtils.TimeoutError; // true
}
// with a custom error message
try {
value = await timeout(myFn(), 1000, 'custom message');
} catch (error){
error.message; // 'custom message'
error instanceof asyncUtils.TimeoutError; // true
}
// with a custom error constructor
try {
value = await timeout(myFn(), 1000, MyCustomError);
} catch (error){
error instanceof MyCustomError; // true
}
asyncUtils.retry(fn, [options]) ⇒ Promise.<*>
Retries a given function an arbitrary number of times optionally delaying retry attempts and / or executing a given function before each retry attempt
Kind: static method of @particle/async-utils
Returns: Promise.<*> - The result of your function
| Param | Type | Default | Description | | --- | --- | --- | --- | | fn | function | | The function you would like to execute and retry upon failure | | [options] | object | | | | [options.maxAttempts] | number | 1 | Number of tries to attempt | | [options.delayMS] | number | | Delay before retrying in milliseconds (optional) | | [options.beforeRetry] | function | | Function to exectute before retrying (optional) |
Example
let value;
try {
value = await retry(myFn, { maxAttempts: 3 });
} catch (error){
error; // the error thrown by your function on it's last attempt
}
// with a delay
try {
value = await retry(myFn, { delayMS: 100, maxAttempts: 3 }); // each retry is delayed for 100ms
} catch (error){
error; // the error thrown by your function on it's last attempt
}
// executing a function before each retry attempt
try {
value = await retry(myFn, { beforeRetry: cleanUpThing, maxAttempts: 3 }); // cleanUpThing() is called before each retry
} catch (error){
error; // the error thrown by your function on it's last attempt
}
asyncUtils.retryWithBackoff(fn, [options]) ⇒ Promise.<*>
Retries a given function an arbitrary number of times exponentially delaying retry attempts and optionally executing a given function before each retry attempt
Kind: static method of @particle/async-utils
Returns: Promise.<*> - The result of your function
| Param | Type | Default | Description | | --- | --- | --- | --- | | fn | function | | The function you would like to execute and retry upon failure | | [options] | object | | | | [options.maxAttempts] | number | 1 | Number of tries to attempt | | [options.factor] | number | 2 | The exponential factor to use - cannot be less than 1 (optional) | | [options.initialDelayMS] | number | 250 | Base delay in milliseconds from which to calculate retry wait time (optional) | | [options.maxDelayMS] | number | Infinity | Maximum delay in milliseconds to enforce after calculating retry wait time (optional) | | [options.beforeRetry] | function | | Function to exectute before retrying (optional) |
Example
let value;
try {
value = await retryWithBackoff(myFn, { maxAttempts: 3 });
// assuming `myFn` resolves on the 3rd and final attempt, call timing is:
// call 0 - immediately
// call 1 - 250ms wait
// call 2 - 1000ms wait
} catch (error){
error; // the error thrown by your function on it's last attempt
}
// with a customized wait
try {
value = await retryWithBackoff(myFn, { factor: 3, initialDelayMS: 100, maxAttempts: 4 });
// assuming `myFn` resolves on the 4th and final attempt, call timing is:
// call 0 - immediately
// call 1 - 100ms wait
// call 2 - 800ms wait
// call 3 - 2700ms wait
} catch (error){
error; // the error thrown by your function on it's last attempt
}
// with a maximum delay limit
try {
value = await retryWithBackoff(myFn, { maxAttempts: 3, maxDelayMS: 500 });
// assuming `myFn` resolves on the 3rd and final attempt, call timing is:
// call 0 - immediately
// call 1 - 250ms wait
// call 2 - 500ms wait
} catch (error){
error; // the error thrown by your function on it's last attempt
}
// executing a function before each retry attempt
try {
value = await retryWithBackoff(myFn, { beforeRetry: cleanUpThing, maxAttempts: 3 }); // cleanUpThing() is called before each retry
} catch (error){
error; // the error thrown by your function on it's last attempt
}
asyncUtils.asyncFilter(array, filter, [concurrency]) ⇒ Promise.<(array|Error)>
Filters an array using an async callback
Kind: static method of @particle/async-utils
Returns: Promise.<(array|Error)> - Your filtered array or an error
| Param | Type | Default | Description | | --- | --- | --- | --- | | array | array | | The array to filter | | filter | function | | Filtering function applied to each element of the array. Return true to keep the element, false otherwise. | | [concurrency] | number | Infinity | The max number of concurrent operations to run |
Example
let values;
try {
values = await asyncFilter([1, 2, 3], async (n) => n % 2 === 0);
values; // [2]
} catch (error){
error; // the first error thrown by your filter function
}
asyncUtils.asyncMap(array, fn, [concurrency]) ⇒ Promise.<(array|Error)>
Map array values using an async callback
Kind: static method of @particle/async-utils
Returns: Promise.<(array|Error)> - New array with mapped values or an error
| Param | Type | Default | Description | | --- | --- | --- | --- | | array | array | | The array to filter | | fn | function | | Function that produces an element of the new Array. | | [concurrency] | number | Infinity | The max number of concurrent operations to run |
Example
let values;
try {
values = await asyncMap([1, 2, 3], async (n) => n + 1);
values; // [2, 3, 4]
} catch (error){
error; // the first error thrown by your mapper function
}
asyncUtils.asyncReduceSeries(array, fn, [initial]) ⇒ Promise.<(value|Error)>
Reduce array values using an async callback executed in series
Kind: static method of @particle/async-utils
Returns: Promise.<(value|Error)> - New reduced valued or an error
| Param | Type | Description | | --- | --- | --- | | array | array | The array to reduce | | fn | function | Function to execute on each element in the array | | [initial] | * | Value used as the 1st argument to the 1st call of the callback (optional) |
Example
let values;
try {
value = await asyncReduceSeries([1, 2, 3], async (out, n) => out + n, 0);
value; // 6
} catch (error){
error; // the first error thrown by your callback function
}
asyncUtils.asyncMapSeries(array, fn) ⇒ Promise.<(array|Error)>
Map array values using an async callback executed in series
Kind: static method of @particle/async-utils
Returns: Promise.<(array|Error)> - New array with mapped values or an error
| Param | Type | Description | | --- | --- | --- | | array | array | The array to map | | fn | function | Function that produces an element of the new Array. |
Example
let values;
try {
values = await asyncMapSeries([1, 2, 3], async (n) => n + 1);
values; // [2, 3, 4]
} catch (error){
error; // the first error thrown by your mapper function
}
asyncUtils.execAsPromise(fn, ...args) ⇒ Promise.<*>
Execute a given function ensuring that its return value or thrown error is transformed into a promise.
Kind: static method of @particle/async-utils
Returns: Promise.<*> - The result of calling your function as a promise
| Param | Type | Description | | --- | --- | --- | | fn | function | Function to execute. | | ...args | * | Arguments to pass to your function. |
Example
let values;
try {
values = await execAsPromise((n) => n + 1, 1, 2, 3);
values; // [2, 3, 4]
} catch (error){
error; // the error thrown by your function
}
asyncUtils.upon(promise) ⇒ Promise.<Array.<{error: Error, value: *}>>
Resolve a promise using await
without try / catch.
Kind: static method of @particle/async-utils
Returns: Promise.<Array.<{error: Error, value: *}>> - The result of your promise as an array like: [error, value]
| Param | Type | Description | | --- | --- | --- | | promise | Promise | Promise to handle |
Example
let [error, value] = await upon(myFn());
if (error){
// handle error
}
console.log(value); // whatever `myFn()` resolved with
asyncUtils.isPromise(x) ⇒ boolean
Determine if input looks like a spec-compliant promsie
Kind: static method of @particle/async-utils
Returns: boolean - Whether or not the given input is a promise
| Param | Type | Description | | --- | --- | --- | | x | * | Value to check |
Example
if (isPromise(x)){
// it's a promise!
} else {
// not a promise!
}
NOTE: Unfortunately, docs have a nasty habit of falling out of date. When in doubt, check usage in tests