@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
-
.TimeoutError ⇐
Error
asyncUtils.TimeoutError ⇐ Kind: static class of @particle/async-utils
Extends: Error
Properties
Name | Type | Default | Description |
---|---|---|---|
[msg] | string |
"The operation timed out" |
The error message |
Promise.<(undefined|Value)>
asyncUtils.delay(ms, [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!');
Promise.<*>
asyncUtils.delayForAtLeast(ms, 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
}
Promise.<*>
asyncUtils.timeout(promise, ms, [Err]) ⇒ 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
}
Promise.<*>
asyncUtils.retry(fn, [options]) ⇒ 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
}
Promise.<*>
asyncUtils.retryWithBackoff(fn, [options]) ⇒ 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
}
Promise.<(array|Error)>
asyncUtils.asyncFilter(array, filter, [concurrency]) ⇒ 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
}
Promise.<(array|Error)>
asyncUtils.asyncMap(array, fn, [concurrency]) ⇒ 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
}
Promise.<(value|Error)>
asyncUtils.asyncReduceSeries(array, fn, [initial]) ⇒ 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
}
Promise.<(array|Error)>
asyncUtils.asyncMapSeries(array, fn) ⇒ 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
}
Promise.<*>
asyncUtils.execAsPromise(fn, ...args) ⇒ 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
}
Promise.<Array.<{error: Error, value: *}>>
asyncUtils.upon(promise) ⇒ 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
boolean
asyncUtils.isPromise(x) ⇒ 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