npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@particle/async-utils

v4.0.2

Published

Collection of promise-based async utility functions

Downloads

1,364

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


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