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 🙏

© 2026 – Pkg Stats / Ryan Hefner

p-suite

v0.4.0

Published

A collection of useful promise utilities

Readme

p-suite

A collection of all of sindresorhus promise modules. This is a fork of promise-fun. It will be periodically updated with the latest upstream changes - package additions/removals etc.

Contents

Installation

npm install p-suite

Usage

import pMemoize from 'p-suite/p-memoize';

const memoized = pMemoize(myFunction);

Or you can use the barrel file if you are confident in your tree-shaker:

import {pMemoize} from 'p-suite';

const memoized = pMemoize.default(myFunction);

Note that that you need to use .default explicitly - there's no mapping of default to named exports.

When should you use p-suite?

If you're not sure which promise module you want to use yet, or you want to use a combination of them, you can get them all from a single install. However, it's very unlikely that you'll need them all, so if you are concerned about the size of your node_modules, you should install the individual packages.

For browser usage, or if bundle size is a concern for any other reason, you can use the individual exports (for example import pMemoize from 'p-suite/p-memoize') without negatively impacting your bundle size.

Please consider sponsoring sindresorhus if you find this package useful.

Packages

  • pify: Promisify a callback-style function
  • delay: Delay a promise a specified amount of time
  • yoctodelay: Delay a promise a specified amount of time
  • p-map: Map over promises concurrently
  • p-all: Run promise-returning & async functions concurrently with optional limited concurrency
  • p-event: Promisify an event by waiting for it to be emitted
  • p-debounce: Debounce promise-returning & async functions
  • p-throttle: Throttle promise-returning & async functions
  • p-timeout: Timeout a promise after a specified amount of time
  • p-retry: Retry a promise-returning or async function
  • p-any: Wait for any promise to be fulfilled
  • p-some: Wait for a specified number of promises to be fulfilled
  • p-mutex: Async mutex lock for managing access to a shared resource
  • p-locate: Get the first fulfilled promise that satisfies the provided testing function
  • p-limit: Run multiple promise-returning & async functions with limited concurrency
  • p-series: Run promise-returning & async functions in series
  • p-memoize: Memoize promise-returning & async functions
  • p-pipe: Compose promise-returning & async functions into a reusable pipeline
  • p-props: Like Promise.all() but for Map and Object
  • p-waterfall: Run promise-returning & async functions in series, each passing its result to the next
  • p-cancelable: Create a promise that can be canceled
  • p-progress: Create a promise that reports progress
  • p-reflect: Make a promise always fulfill with its actual fulfillment value or rejection reason
  • p-filter: Filter promises concurrently
  • p-reduce: Reduce a list of values using promises into a promise for a value
  • p-settle: Settle promises concurrently and get their fulfillment value or rejection reason with optional limited concurrency
  • p-map-series: Map over promises serially
  • p-each-series: Iterate over promises serially
  • p-times: Run promise-returning & async functions a specific number of times concurrently
  • p-lazy: Create a lazy promise that defers execution until it's awaited or when .then(), .catch(), or .finally() is called
  • p-whilst: While a condition returns true, calls a function repeatedly, and then resolves the promise
  • p-do-whilst: Calls a function repeatedly while a condition returns true and then resolves the promise
  • p-forever: Run promise-returning & async functions repeatedly until you end it
  • p-wait-for: Wait for a condition to be true
  • p-min-delay: Delay a promise a minimum amount of time
  • p-try: `Start a promise chain
  • p-race: A better Promise.race()
  • p-immediate: Returns a promise resolved in the next event loop - think setImmediate()
  • p-time: Measure the time a promise takes to resolve
  • p-defer: Create a deferred promise
  • p-is-promise: Check if something is a promise
  • p-state: Inspect the state of a promise
  • p-queue: Promise queue with concurrency control
  • make-synchronous: Make an asynchronous function synchronous

Other useful promise-related packages

Not part of promise-fun but often useful in combination with some of the packages above

  • expiry-map: A Map implementation with expirable items
  • quick-lru: Simple “Least Recently Used” (LRU) cache
  • lru-cache: A cache object that deletes the least-recently-used items.
  • stale-while-revalidate-cache: This small battle-tested TypeScript library is a storage-agnostic helper that implements a configurable stale-while-revalidate caching strategy for any functions, for any JavaScript environment.
  • memoize: Memoize functions - An optimization used to speed up consecutive function calls by caching the result of calls with identical input
  • dataloader: A data loading utility to reduce requests to a backend via batching and caching.

.then/.catch-based packages

You should generally avoid using .then except in edge cases

  • p-catch-if: Conditional promise catch handler
  • p-if: Conditional promise chains
  • p-tap: Tap into a promise chain without affecting its value or state
  • p-log: Log the value/error of a promise
  • p-break: Break out of a promise chain

Docs

pify

Documenation from source package | Back to packages

Promisify a callback-style function

Install
npm install p-suite
Usage
import fs from 'fs';
import pify from 'p-suite/pify';

// Promisify a single function.
const data = await pify(fs.readFile)('package.json', 'utf8');
console.log(JSON.parse(data).name);
//=> 'pify'

// Promisify all methods in a module.
const data2 = await pify(fs).readFile('package.json', 'utf8');
console.log(JSON.parse(data2).name);
//=> 'pify'
API

#####(input, options?)

Returns a Promise wrapped version of the supplied function or module.

input

Type: Function | object

Callback-style function or module whose methods you want to promisify.

options

Type: object

multiArgs

Type: boolean
Default: false

By default, the promisified function will only return the second argument from the callback, which works fine for most APIs. This option can be useful for modules like request that return multiple arguments. Turning this on will make it return an array of all arguments from the callback, excluding the error argument, instead of just the second argument. This also applies to rejections, where it returns an array of all the callback arguments, including the error.

import request from 'request';
import pify from 'p-suite/pify';

const pRequest = pify(request, {multiArgs: true});

const [httpResponse, body] = await pRequest('https://sindresorhus.com');

see the rest of the docs in the source package

delay

Documenation from source package | Back to packages

Delay a promise a specified amount of time

[!TIP] If you target Node.js only, you can use import {setTimeout} from 'node:timers/promises'; await setTimeout(1000); instead. This package can still be useful if you need browser support or the extra features.

Install
npm install p-suite
Usage
import delay from 'p-suite/delay';

bar();

await delay(100);

// Executed 100 milliseconds later
baz();
API

#####(milliseconds, options?) default import

Create a promise which resolves after the specified milliseconds.

rangeDelay(minimum, maximum, options?)

Create a promise which resolves after a random amount of milliseconds between minimum and maximum has passed.

Useful for tests and web scraping since they can have unpredictable performance. For example, if you have a test that asserts a method should not take longer than a certain amount of time, and then run it on a CI, it could take longer. So with this method, you could give it a threshold instead.

milliseconds
mininum
maximum

Type: number

Milliseconds to delay the promise.

Unlike native setTimeout, this supports unlimited delay length.

options

Type: object

see the rest of the docs in the source package

yoctodelay

Documenation from source package | Back to packages

Delay a promise a specified amount of time

It's less than half the size of the nanodelay module.

Note: If you target Node.js 16 or later, you can use the built-in functionality instead:

import {setTimeout as delay} from 'node:timers/promises';

await delay(100);
Install
$ npm install p-suite
Usage
import delay from 'p-suite/yoctodelay';

foo();

await delay(100);

// Executed 100 milliseconds later
bar();
API
delay(milliseconds)

Delay the promise and then resolve.

milliseconds

Type: number

The duration to delay the promise.

FAQ
What is yocto?

It's the smallest official unit prefix in the metric system. Much smaller than nano.

see the rest of the docs in the source package

p-map

Documenation from source package | Back to packages

Map over promises concurrently

Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently.

This is different from Promise.all() in that you can control the concurrency and also decide whether or not to stop iterating when there's an error.

Install
npm install p-suite
Usage
import pMap from 'p-suite/p-map';
import got from 'got';

const sites = [
	getWebsiteFromUsername('sindresorhus'), //=> Promise
	'https://avajs.dev',
	'https://github.com'
];

const mapper = async site => {
	const {requestUrl} = await got.head(site);
	return requestUrl;
};

const result = await pMap(sites, mapper, {concurrency: 2});

console.log(result);
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']
API
pMap(input, mapper, options?)

Returns a Promise that is fulfilled when all promises in input and ones returned from mapper are fulfilled, or rejects if any of the promises reject. The fulfilled value is an Array of the fulfilled values returned from mapper in input order.

pMapIterable(input, mapper, options?)

Returns an async iterable that streams each return value from mapper in order.

import {pMapIterable} from 'p-suite/p-map';

// Multiple posts are fetched concurrently, with limited concurrency and backpressure
for await (const post of pMapIterable(postIds, getPostMetadata, {concurrency: 8})) {
	console.log(post);
}

see the rest of the docs in the source package

p-all

Documenation from source package | Back to packages

Run promise-returning & async functions concurrently with optional limited concurrency

Similar to Promise.all(), but accepts functions instead of promises directly so you can limit the concurrency.

If you're doing the same work in each function, use p-map instead.

See p-series for a serial counterpart.

Install
npm install p-suite
Usage
import pAll from 'p-suite/p-all';
import got from 'got';

const actions = [
	() => got('https://sindresorhus.com'),
	() => got('https://avajs.dev'),
	() => checkSomething(),
	() => doSomethingElse()
];

console.log(await pAll(actions, {concurrency: 2}));
API
pAll(tasks, options?)

Returns a Promise that is fulfilled when all promises returned from calling the functions in tasks are fulfilled, or rejects if any of the promises reject. The fulfilled value is an Array of the fulfilled values in tasks order.

tasks

Type: Iterable<Function>

Iterable with promise-returning/async functions.

options

Type: object

concurrency

Type: number (Integer)
Default: Infinity
Minimum: 1

Number of concurrently pending promises.

see the rest of the docs in the source package

p-event

Documenation from source package | Back to packages

Promisify an event by waiting for it to be emitted

Useful when you need only one event emission and want to use it with promises or await it in an async function.

It works with any event API in Node.js and the browser (using a bundler).

If you want multiple individual events as they are emitted, you can use the pEventIterator() method. Observables can be useful too.

Install
npm install p-suite
Usage

In Node.js:

import {pEvent} from 'p-suite/p-event';
import emitter from './some-event-emitter';

try {
	const result = await pEvent(emitter, 'finish');

	// `emitter` emitted a `finish` event
	console.log(result);
} catch (error) {
	// `emitter` emitted an `error` event
	console.error(error);
}

In the browser:

import {pEvent} from 'p-suite/p-event';

await pEvent(document, 'DOMContentLoaded');
console.log('😎');

Async iteration:

import {pEventIterator} from 'p-suite/p-event';
import emitter from './some-event-emitter';

const asyncIterator = pEventIterator(emitter, 'data', {
	resolutionEvents: ['finish']
});

for await (const event of asyncIterator) {
	console.log(event);
}

see the rest of the docs in the source package

p-debounce

Documenation from source package | Back to packages

Debounce promise-returning & async functions

Install
npm install p-suite
Usage
import pDebounce from 'p-suite/p-debounce';

const expensiveCall = async input => input;

const debouncedFunction = pDebounce(expensiveCall, 200);

for (const number of [1, 2, 3]) {
	(async () => {
		console.log(await debouncedFunction(number));
	})();
}
//=> 3
//=> 3
//=> 3
API
pDebounce(fn, wait, options?)

Returns a function that delays calling fn until after wait milliseconds have elapsed since the last time it was called.

fn

Type: Function

Promise-returning/async function to debounce.

wait

Type: number

Milliseconds to wait before calling fn.

options

Type: object

see the rest of the docs in the source package

p-throttle

Documenation from source package | Back to packages

Throttle promise-returning & async functions

Also works with normal functions.

It rate-limits function calls without discarding them, making it ideal for external API interactions where avoiding call loss is crucial. All calls are queued and executed—the last call is guaranteed to run with its original context and arguments preserved.

Install
npm install p-suite
Browser

This package works in the browser with modern browsers that support WeakRef and FinalizationRegistry (Chrome 84+, Firefox 79+, Safari 14.1+, Edge 84+).

Usage

This calls the function at most twice per second:

import pThrottle from 'p-suite/p-throttle';

const now = Date.now();

const throttle = pThrottle({
	limit: 2,
	interval: 1000
});

const throttled = throttle(async index => {
	const secDiff = ((Date.now() - now) / 1000).toFixed();
	return `${index}: ${secDiff}s`;
});

for (let index = 1; index <= 6; index++) {
	(async () => {
		console.log(await throttled(index));
	})();
}
//=> 1: 0s
//=> 2: 0s
//=> 3: 1s
//=> 4: 1s
//=> 5: 2s
//=> 6: 2s

see the rest of the docs in the source package

p-timeout

Documenation from source package | Back to packages

Timeout a promise after a specified amount of time

[!NOTE] You may want to use AbortSignal.timeout() instead. Learn more.

Install
npm install p-suite
Usage
import {setTimeout} from 'node:timers/promises';
import pTimeout from 'p-suite/p-timeout';

const delayedPromise = setTimeout(200);

await pTimeout(delayedPromise, {
	milliseconds: 50
});
//=> [TimeoutError: Promise timed out after 50 milliseconds]
API
pTimeout(input, options)

Returns a decorated input that times out after milliseconds time. It has a .clear() method that clears the timeout.

If you pass in a cancelable promise, specifically a promise with a .cancel() method, that method will be called when the pTimeout promise times out.

input

Type: Promise

Promise to decorate.

options

Type: object

milliseconds

Type: number

Milliseconds before timing out.

Passing Infinity will cause it to never time out.

see the rest of the docs in the source package

p-retry

Documenation from source package | Back to packages

Retry a promise-returning or async function

It does exponential backoff and supports custom retry strategies for failed operations.

Install
npm install p-suite
Usage
import pRetry, {AbortError} from 'p-suite/p-retry';

const run = async () => {
	const response = await fetch('https://sindresorhus.com/unicorn');

	// Abort retrying if the resource doesn't exist
	if (response.status === 404) {
		throw new AbortError(response.statusText);
	}

	return response.blob();
};

console.log(await pRetry(run, {retries: 5}));
API
pRetry(input, options?)

Returns a Promise that is fulfilled when calling input returns a fulfilled promise. If calling input returns a rejected promise, input is called again until the max retries are reached, it then rejects with the last rejection reason.

Does not retry on most TypeErrors, with the exception of network errors. This is done on a best case basis as different browsers have different messages to indicate this. See whatwg/fetch#526 (comment)

input

Type: Function

Receives the number of attempts as the first argument and is expected to return a Promise or any value.

options

Type: object

onFailedAttempt(context)

Type: Function

Callback invoked on each failure. Receives a context object containing the error and retry state information.

The function is called before shouldConsumeRetry and shouldRetry, for all errors except AbortError.

If the function throws, all retries will be aborted and the original promise will reject with the thrown error.

import pRetry from 'p-suite/p-retry';

const run = async () => {
	const response = await fetch('https://sindresorhus.com/unicorn');

	if (!response.ok) {
		throw new Error(response.statusText);
	}

	return response.json();
};

const result = await pRetry(run, {
	onFailedAttempt: ({error, attemptNumber, retriesLeft, retriesConsumed}) => {
		console.log(`Attempt ${attemptNumber} failed. ${retriesLeft} retries left. ${retriesConsumed} retries consumed.`);
		// 1st request => Attempt 1 failed. 5 retries left. 0 retries consumed.
		// 2nd request => Attempt 2 failed. 4 retries left. 1 retries consumed.
		// …
	},
	retries: 5
});

console.log(result);

The onFailedAttempt function can return a promise. For example, to add a delay:

import pRetry from 'p-suite/p-retry';
import delay from 'delay';

const run = async () => { … };

const result = await pRetry(run, {
	onFailedAttempt: async () => {
		console.log('Waiting for 1 second before retrying');
		await delay(1000);
	}
});

see the rest of the docs in the source package

p-any

Documenation from source package | Back to packages

Wait for any promise to be fulfilled

Useful when you need the fastest promise.

You probably want this instead of Promise.race(). Reason.

With Node.js 15, there's now a built-in Promise#any method. The benefit of this package is that it has cancellation functionality.

Install
$ npm install p-suite
Usage

Checks 3 websites and logs the fastest.

import pAny from 'p-suite/p-any';
import got from 'got';

const first = await pAny([
	got.head('https://github.com').then(() => 'github'),
	got.head('https://google.com').then(() => 'google'),
	got.head('https://twitter.com').then(() => 'twitter')
]);

console.log(first);
//=> 'google'
API
pAny(input, options?)

Returns a cancelable Promise that is fulfilled when any promise from input is fulfilled. If all the input promises reject, it will reject with an AggregateError error.

input

Type: Iterable<Promise | unknown>

options

Type: object

filter

Type: Function

Receives the value resolved by the promise. Used to filter out values that doesn't satisfy a condition.

see the rest of the docs in the source package

p-some

Documenation from source package | Back to packages

Wait for a specified number of promises to be fulfilled

Useful when you need the fastest of multiple promises.

Install
npm install p-suite
Usage

Checks 4 websites and logs the 2 fastest.

import got from 'got';
import pSome from 'p-suite/p-some';

const input = [
	got.head('github.com').then(() => 'github'),
	got.head('google.com').then(() => 'google'),
	got.head('twitter.com').then(() => 'twitter'),
	got.head('medium.com').then(() => 'medium')
];

const [first, second] = await pSome(input, {count: 2});

console.log(first, second);
//=> 'google twitter'
API
pSome(input, options)

Returns a Promise that is fulfilled when count promises from input are fulfilled. The fulfilled value is an Array of the values from the input promises in the order they were fulfilled. If it becomes impossible to satisfy count, for example, too many promises rejected, it will reject with an AggregateError. The promise can be aborted using the signal option.

input

Type: Iterable<Promise | unknown>

An Iterable collection of promises/values to wait for.

options

Type: object

count

Required
Type: number
Minimum: 1

Number of promises from input that have to be fulfilled until the returned promise is fulfilled.

see the rest of the docs in the source package

p-mutex

Documenation from source package | Back to packages

Async mutex lock for managing access to a shared resource

It provides a safe and easy way to ensure that only one operation accesses a particular resource at a time, preventing race conditions and ensuring data integrity.

Install
npm install p-suite
Usage
import Mutex from 'p-suite/p-mutex';

const mutex = new Mutex();

const sharedArray = [];

async function addToSharedArray(item) {
	await mutex.withLock(async () => {
		const item = await getItem();
		sharedArray.push(item);
	});
}

addToSharedArray('A');
addToSharedArray('B');
API
Mutex()

Creates a new mutex object.

.withLock(task)

Automatically manages the lock during the execution of the given task.

It ensures that the mutex is locked before the task executes and automatically releases the lock afterward, even if an error occurs during the execution.

Parameters:

  • task: A function that performs the actions you want to execute while the lock is held. It can be async.

Returns the result of the task function.

[!TIP] Prefer using this method for most use cases as it handles the complexities of lock management and is less prone to errors. Use the lock and unlock methods directly only when you need more control over the lock management process.

see the rest of the docs in the source package

p-locate

Documenation from source package | Back to packages

Get the first fulfilled promise that satisfies the provided testing function

Think of it like an async version of Array#find.

Install
npm install p-suite
Usage

Here we find the first file that exists on disk, in array order.

import {pathExists} from 'path-exists';
import pLocate from 'p-suite/p-locate';

const files = [
	'unicorn.png',
	'rainbow.png', // Only this one actually exists on disk
	'pony.png'
];

const foundPath = await pLocate(files, file => pathExists(file));

console.log(foundPath);
//=> 'rainbow.png'

The above is just an example. Use locate-path if you need this.

API
pLocate(input, tester, options?)

Returns a Promise that is fulfilled when tester resolves to true or the iterable is done, or rejects if any of the promises reject. The fulfilled value is the current iterable value or undefined if tester never resolved to true.

input

Type: Iterable<Promise | unknown> | AsyncIterable<unknown>

An iterable or async iterable of promises/values to test.

When an AsyncIterable is given, it is iterated serially and the concurrency and preserveOrder options are not applicable.

tester(element)

Type: Function

This function will receive resolved values from input and is expected to return a Promise<boolean> or boolean.

see the rest of the docs in the source package

p-limit

Documenation from source package | Back to packages

Run multiple promise-returning & async functions with limited concurrency

Works in Node.js and browsers.

Install
npm install p-suite
Usage
import pLimit from 'p-suite/p-limit';

const limit = pLimit(1);

const input = [limit(() => fetchSomething('foo')), limit(() => fetchSomething('bar')), limit(() => doSomething())];

// Only one promise is run at once
const result = await Promise.all(input);
console.log(result);
API
pLimit(concurrency) default export

Returns a limit function.

concurrency

Type: number | object
Minimum: 1

Concurrency limit.

You can pass a number or an options object with a concurrency property.

rejectOnClear

Type: boolean
Default: false

Reject pending promises with an AbortError when clearQueue() is called. This is recommended if you await the returned promises, for example with Promise.all, so pending tasks do not remain unresolved after clearQueue().

import pLimit from 'p-suite/p-limit';

const limit = pLimit({concurrency: 1});

see the rest of the docs in the source package

p-series

Documenation from source package | Back to packages

Run promise-returning & async functions in series

Note: You can just use await in a for-loop to get the same behavior. This package was useful before async/await existed.

If you're doing the same work in each function, use p-each-series instead.

See p-all for a concurrent counterpart.

Install
$ npm install p-suite
Usage
import pSeries from 'p-suite/p-series';
import got from 'got';

const tasks = [() => got('https://sindresorhus.com'), () => checkSomething(), () => doSomethingElse()];

console.log(await pSeries(tasks));
API
pSeries(tasks)

Returns a Promise that is fulfilled when all promises returned from calling the functions in tasks are fulfilled, or rejects if any of the promises reject. The fulfilled value is an Array of the fulfilled values.

tasks

Type: Iterable<Function>

Functions are expected to return a value. If a Promise is returned, it's awaited before continuing with the next task.

Related
  • p-all - Run promise-returning & async functions concurrently with optional limited concurrency
  • p-waterfall - Run promise-returning & async functions in series, each passing its result to the next
  • p-each-series - Iterate over promises serially
  • More…

p-memoize

Documenation from source package | Back to packages

Memoize promise-returning & async functions

Useful for speeding up consecutive function calls by caching the result of calls with identical input.

By default, only the memoized function's first argument is considered via strict equality comparison. If you need to cache multiple arguments or cache objects by value, have a look at alternative caching strategies below.

This package is similar to memoize but with async-specific enhancements; in particular, it allows for asynchronous caches and does not cache rejected promises.

Install
npm install p-suite
Usage
import pMemoize from 'p-suite/p-memoize';
import got from 'got';

const memoizedGot = pMemoize(got);

await memoizedGot('https://sindresorhus.com');

// This call is cached
await memoizedGot('https://sindresorhus.com');
Caching strategy

Similar to the caching strategy for memoize with the following exceptions:

  • Promises returned from a memoized function are locally cached until resolving, when their value is added to cache. Special properties assigned to a returned promise will not be kept after resolution and every promise may need to resolve with a serializable object if caching results in a database.
  • .get(), .has() and .set() methods on cache can run asynchronously by returning a promise.
  • Instead of .set() being provided an object with the properties value and maxAge, it will only be provided value as the first argument. If you want to implement time-based expiry, consider doing so in cache.
API
pMemoize(fn, options?)

Returns a memoized version of the given function.

fn

Type: Function

Promise-returning or async function to be memoized.

see the rest of the docs in the source package

p-pipe

Documenation from source package | Back to packages

Compose promise-returning & async functions into a reusable pipeline

Install
$ npm install p-suite
Usage
import pPipe from 'p-suite/p-pipe';

const addUnicorn = async string => `${string} Unicorn`;
const addRainbow = async string => `${string} Rainbow`;

const pipeline = pPipe(addUnicorn, addRainbow);

console.log(await pipeline('❤️'));
//=> '❤️ Unicorn Rainbow'
API
pPipe(input…)

The input functions are applied from left to right.

input

Type: Function

Expected to return a Promise or any value.

Related
  • p-each-series - Iterate over promises serially
  • p-series - Run promise-returning & async functions in series
  • p-waterfall - Run promise-returning & async functions in series, each passing its result to the next
  • More…

p-props

Documenation from source package | Back to packages

Like Promise.all() but for Map and Object

Useful when you need to run multiple promises concurrently and keep track of the fulfilled values by name.

Install
npm install p-suite
Usage
import pProps from 'p-suite/p-props';
import got from 'got';

const fetch = async url => {
	const {body} = await got(url);
	return body;
};

const sites = {
	ava: fetch('https://avajs.dev'),
	todomvc: fetch('https://todomvc.com'),
	github: fetch('https://github.com'),
	foo: 'bar'
};

console.log(await pProps(sites));
/*
{
	ava: '<!doctype …',
	todomvc: '<!doctype …',
	github: '<!doctype …',
	foo: 'bar'
}
*/
API
pProps(input, mapper?, options?)

Returns a Promise that is fulfilled when all promises in input and ones returned from mapper are fulfilled, or rejects if any of the promises reject. The fulfilled value is the same as input, but with a fulfilled version of each entry value, or the fulfilled value returned from mapper, if defined.

input

Type: Map | object

Resolves entry values that are promises. Other values are passed through.

see the rest of the docs in the source package

p-waterfall

Documenation from source package | Back to packages

Run promise-returning & async functions in series, each passing its result to the next

Install
$ npm install p-suite
Usage
import pWaterfall from 'p-suite/p-waterfall';

const tasks = [initialValue => getEmoji(initialValue), previousValue => `I ❤️ ${previousValue}`];

console.log(await pWaterfall(tasks, 'unicorn'));
//=> 'I ❤️ 🦄'
API
pWaterfall(tasks, initialValue?)

Returns a Promise that is fulfilled when all promises returned from calling the functions in tasks are fulfilled, or rejects if any of the promises reject. The fulfilled value is the value returned from the last task.

tasks

Type: Iterable<Function>

Functions are expected to return a value. If a Promise is returned, it's awaited before continuing with the next task.

initialValue

Type: unknown

Value to use as previousValue in the first task.

Related

p-cancelable

Documenation from source package | Back to packages

Create a promise that can be canceled

Useful for animation, loading resources, long-running async computations, async iteration, etc.

If you target Node.js 16 or later, this package is less useful and you should probably use AbortController instead.

Install
npm install p-suite
Usage
import PCancelable from 'p-suite/p-cancelable';

const cancelablePromise = new PCancelable((resolve, reject, onCancel) => {
	const worker = new SomeLongRunningOperation();

	onCancel(() => {
		worker.close();
	});

	worker.on('finish', resolve);
	worker.on('error', reject);
});

// Cancel the operation after 10 seconds
setTimeout(() => {
	cancelablePromise.cancel('Unicorn has changed its color');
}, 10000);

try {
	console.log('Operation finished successfully:', await cancelablePromise);
} catch (error) {
	if (cancelablePromise.isCanceled) {
		// Handle the cancelation here
		console.log('Operation was canceled');
		return;
	}

	throw error;
}
API

see the rest of the docs in the source package

p-progress

Documenation from source package | Back to packages

Create a promise that reports progress

Useful for reporting progress to the user during long-running async operations.

Install
npm install p-suite
Usage
import pProgress from 'p-suite/p-progress';

const runJob = async name =>
	pProgress(async progress => {
		const job = new Job(name);

		job.on('data', data => {
			progress(data.length / job.totalSize);
		});

		await job.run();
	});

const progressPromise = runJob('Gather rainbows');

progressPromise.onProgress(console.log);
//=> 0.09
//=> 0.23
//=> 0.59
//=> 0.75
//=> 1

await progressPromise;
API
pProgress(function)

Convenience method to make your promise-returning or async function report progress.

The function you specify will be passed the progress() function as a parameter.

instance = new PProgress(executor)

Same as the Promise constructor, but with an appended progress parameter in executor.

PProgress is a subclass of Promise.

see the rest of the docs in the source package

p-reflect

Documenation from source package | Back to packages

Make a promise always fulfill with its actual fulfillment value or rejection reason

Useful when you want a promise to fulfill no matter what and would rather handle the actual state afterwards.

Install
$ npm install p-suite
Usage

Here, Promise.all would normally fail early because one of the promises rejects, but by using p-reflect, we can ignore the rejection and handle it later on.

import pReflect from 'p-suite/p-reflect';

const promises = [getPromise(), getPromiseThatRejects(), getPromise()];

const results = await Promise.all(promises.map(pReflect));

console.log(results);
/*
[
	{
		status: 'fulfilled',
		value: '🦄'
		isFulfilled: true,
		isRejected: false
	},
	{
		status: 'rejected',
		reason: [Error: 👹]
		isFulfilled: false,
		isRejected: true
	},
	{
		status: 'fulfilled',
		value: '🐴'
		isFulfilled: true,
		isRejected: false
	}
]
*/

const resolvedString = results
	.filter(result => result.isFulfilled)
	.map(result => result.value)
	.join('');

console.log(resolvedString);
//=> '🦄🐴'

The above is just an example. Use p-settle if you need exactly that.

see the rest of the docs in the source package

p-filter

Documenation from source package | Back to packages

Filter promises concurrently

Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently and get a filtered down result.

Install
npm install p-suite
Usage
import pFilter from 'p-suite/p-filter';
import getWeather from 'get-weather'; // Not a real module

const places = [getCapital('Norway').then(info => info.name), 'Bangkok, Thailand', 'Berlin, Germany', 'Tokyo, Japan'];

const filterer = async place => {
	const weather = await getWeather(place);
	return weather.temperature > 30;
};

const result = await pFilter(places, filterer);

console.log(result);
//=> ['Bangkok, Thailand']
API
pFilter(input, filterer, options?)

Returns a Promise that is fulfilled when all promises in input and ones returned from filterer are fulfilled, or rejects if any of the promises reject. The fulfilled value is an Array of the fulfilled values returned from filterer in input order.

input

Type: Iterable<Promise<unknown> | unknown>

Iterated over concurrently in the filterer function.

filterer(element, index)

Type: Function

The filterer function that decides whether an element should be included into result. Expected to return boolean | Promise<boolean>.

see the rest of the docs in the source package

p-reduce

Documenation from source package | Back to packages

Reduce a list of values using promises into a promise for a value

Useful when you need to calculate some accumulated value based on async resources.

Install
$ npm install p-suite
Usage
import pReduce from 'p-suite/p-reduce';
import humanInfo from 'human-info'; // Not a real module

const names = [getUser('sindresorhus').then(info => info.name), 'Addy Osmani', 'Pascal Hartig', 'Stephen Sawchuk'];

const totalAge = await pReduce(
	names,
	async (total, name) => {
		const info = await humanInfo(name);
		return total + info.age;
	},
	0
);

console.log(totalAge);
//=> 125
API
pReduce(input, reducer, initialValue?)

Returns a Promise that is fulfilled when all promises in input and ones returned from reducer are fulfilled, or rejects if any of the promises reject. The fulfilled value is the result of the reduction.

input

Type: Iterable<Promise|any>

Iterated over serially in the reducer function.

reducer(previousValue, currentValue, index)

Type: Function

Expected to return a value. If a Promise is returned, it's awaited before continuing with the next iteration.

see the rest of the docs in the source package

p-settle

Documenation from source package | Back to packages

Settle promises concurrently and get their fulfillment value or rejection reason with optional limited concurrency

Install
npm install p-suite
Usage
import fs from 'node:fs/promises';
import pSettle from 'p-suite/p-settle';

const files = [
	'a.txt',
	'b.txt' // Doesn't exist
].map(filename => fs.readFile(filename, 'utf8'));

console.log(await pSettle(files));
/*
[
	{
		status: 'fulfilled',
		value: '🦄',
		isFulfilled: true,
		isRejected: false,
	},
	{
		status: 'rejected',
		reason: [Error: ENOENT: no such file or directory, open 'b.txt'],
		isFulfilled: false,
		isRejected: true,
	}
]
*/

With a mapper function:

import fs from 'node:fs/promises';
import pSettle from 'p-suite/p-settle';

const files = ['a.txt', 'b.txt']; // Filenames

console.log(
	await pSettle(files, {
		mapper: filename => fs.readFile(filename, 'utf8'),
		concurrency: 2
	})
);
/*
[
	{
		status: 'fulfilled',
		value: '🦄',
		isFulfilled: true,
		isRejected: false,
	},
	{
		status: 'rejected',
		reason: [Error: ENOENT: no such file or directory, open 'b.txt'],
		isFulfilled: false,
		isRejected: true,
	}
]
*/

see the rest of the docs in the source package

p-map-series

Documenation from source package | Back to packages

Map over promises serially

Useful as a side-effect mapper. Use p-map if you don't need side-effects, as it's concurrent.

Install
$ npm install p-suite
Usage
import pMapSeries from 'p-suite/p-map-series';

const keywords = [
	getTopKeyword() //=> Promise
	'rainbow',
	'pony'
];

let scores = [];

const mapper = async keyword => {
	const score = await fetchScore(keyword);
	scores.push(score);
	return {keyword, score};
});

console.log(await pMapSeries(keywords, mapper));
/*
[
	{
		keyword: 'unicorn',
		score: 99
	},
	{
		keyword: 'rainbow',
		score: 70
	},
	{
		keyword: 'pony',
		score: 79
	}
]
*/

see the rest of the docs in the source package

p-each-series

Documenation from source package | Back to packages

Iterate over promises serially

Useful as a side-effect iterator. Prefer p-map if you don't need side-effects, as it's concurrent.

Install
$ npm install p-suite
Usage
import pEachSeries from 'p-suite/p-each-series';

const keywords = [
	getTopKeyword(), //=> Promise
	'rainbow',
	'pony'
];

const iterator = async element => saveToDiskPromise(element);

console.log(await pEachSeries(keywords, iterator));
//=> ['unicorn', 'rainbow', 'pony']
API
pEachSeries(input, iterator)

Returns a Promise that is fulfilled when all promises in input and ones returned from iterator are fulfilled, or rejects if any of the promises reject. The fulfillment value is the original input.

input

Type: Iterable<Promise | unknown>

Iterated over serially in the iterator function.

iterator(element, index)

Type: Function

Return value is ignored unless it's Promise, then it's awaited before continuing with the next iteration.

pEachSeries.stop

Stop iterating through items by returning pEachSeries.stop from the iterator function.

import pEachSeries from 'p-suite/p-each-series';

// Logs `a` and `b`.
const result = await pEachSeries(['a', 'b', 'c'], value => {
	console.log(value);

	if (value === 'b') {
		return pEachSeries.stop;
	}
});

console.log(result);
//=> ['a', 'b', 'c']

see the rest of the docs in the source package

p-times

Documenation from source package | Back to packages

Run promise-returning & async functions a specific number of times concurrently

Install
$ npm install p-suite
Usage
import pTimes from 'p-suite/p-times';

const result = await pTimes(5, index => createFixture(`🦄-${index + 1}`));

console.log(`Created fixtures: ${result.join(' ')}`);
//=> 'Created fixtures: 🦄-1 🦄-2 🦄-3 🦄-4 🦄-5'
API
pTimes(count, mapper, options?)

Returns a Promise that is fulfilled when all promises returned from mapper are fulfilled, or rejects if any of the promises reject. The fulfilled value is an Array of the fulfilled values returned from mapper in order.

count

Type: number

Number of times to call mapper.

mapper(index)

Type: Function

Expected to return a Promise or value.

options

Type: object

concurrency

Type: number
Default: Infinity
Minimum: 1

Number of concurrently pending promises returned by mapper.

see the rest of the docs in the source package

p-lazy

Documenation from source package | Back to packages

Create a lazy promise that defers execution until it's awaited or when .then(), or .catch(), or .finally() is called

Useful if you're doing some heavy operations and would like to only do it when the promise is actually used.

Install
npm install p-suite
Usage
import PLazy from 'p-suite/p-lazy';

const lazyPromise = new PLazy(resolve => {
	someHeavyOperation(resolve);
});

// `someHeavyOperation` is not yet called

await doSomethingFun;

// `someHeavyOperation` is called
console.log(await lazyPromise);
API
new PLazy(executor)

Same as the Promise constructor. PLazy is a subclass of Promise.

PLazy.from(fn)

Create a PLazy promise from a promise-returning or async function.

PLazy.resolve(value)

Create a PLazy promise that is resolved with the given value, or the promise passed as value.

PLazy.reject(reason)

Create a PLazy promise that is rejected with the given reason.

Related

p-whilst

Documenation from source package | Back to packages

While a condition returns true, calls a function repeatedly, and then resolves the promise

Think async version of the while statement.

Install
npm install p-suite
Usage
import pWhilst from 'p-suite/p-whilst';

let count = 0;

await pWhilst(
	() => count < 5,
	() => count++
);

console.log(count);
//=> 5
API
pWhilst(condition, action, initialValue?)

While condition returns true, executes action repeatedly, and then resolves the promise to the result of the last call to action. Rejects if action returns a promise that rejects or if an error is thrown anywhere.

condition

Type: Function Arguments: The value the action function returns or initialValue for the first iteration.

Expected to return a boolean or a Promise<boolean> that indicates whether to execute action.

action

Type: Function Arguments: The value the last call to action function returns.

Action to run for each iteration.

You can return a promise and it will be handled.

see the rest of the docs in the source package

p-do-whilst

Documenation from source package | Back to packages

Calls a function repeatedly while a condition returns true and then resolves the promise

Think async version of the do…while statement.

Install
npm install p-suite
Usage

Choose your preferred style:

import pDoWhilst from 'p-suite/p-do-whilst';

let count = 0;

await pDoWhilst(
	() => count++,
	() => count < 5
);

console.log(count);
//=> 5

Or:

import pDoWhilst from 'p-suite/p-do-whilst';

const count = await pDoWhilst(
	currentCount => currentCount + 1,
	currentCount => currentCount < 5,
	0
);

console.log(count);
//=> 5
API
pDoWhilst(action, condition, initialValue?)

Executes action repeatedly while condition returns true and then resolves to the result of the last call to action. Rejects if action returns a promise that rejects or if an error is thrown anywhere.

see the rest of the docs in the source package

p-forever

Documenation from source package | Back to packages

Run promise-returning & async functions until you end it

Think of it like an async version of while (true) {}.

Install
npm install p-suite
Usage

Here we create some numbered fixtures. The createFixture() function returns a Promise.

import pForever from 'p-suite/p-forever';

pForever(
	async index => {
		index++;

		if (index > 100) {
			return pForever.end;
		}

		await createFixture(index);

		return index;
	},
	{initialValue: 0}
);

or

import pForever from 'p-suite/p-forever';

let index = 0;

pForever(async () => {
	index++;

	if (index > 100) {
		return pForever.end;
	}

	await createFixture(index);
});

see the rest of the docs in the source package

p-wait-for

Documenation from source package | Back to packages

Wait for a condition to be true

Can be useful for polling.

Install
npm install p-suite
Usage
import pWaitFor from 'p-suite/p-wait-for';
import {pathExists} from 'path-exists';

await pWaitFor(() => pathExists('unicorn.png'));
console.log('Yay! The file now exists.');
API
pWaitFor(condition, options?)

Returns a Promise that resolves when condition returns true. Rejects if condition throws or returns a Promise that rejects.

condition

Type: Function

Expected to return Promise<boolean> | boolean or a value from pWaitFor.resolveWith().

options

Type: object

interval

Type: number
Default: 20

Number of milliseconds to wait after condition resolves to false before calling it again.

timeout

Type: number | TimeoutOptions
Default: Infinity

Number of milliseconds to wait before automatically rejecting with a TimeoutError.

You can customize the timeout Error by specifying TimeoutOptions.

import pWaitFor from 'p-suite/p-wait-for';
import {pathExists} from 'path-exists';

await pWaitFor(() => pathExists('unicorn.png'), {
	timeout: {
		milliseconds: 100,
		message: new Error('Time’s up!')
	}
});

console.log('Yay! The file now exists.');

see the rest of the docs in the source package

p-min-delay

Documenation from source package | Back to packages

Delay a promise a minimum amount of time

While the delay module delays the promise a specified amount of time and then resolves it, this module ensures the promise resolves after the specified amount of time.

Useful when you have a promise that may settle immediately or may take some time, and you want to ensure it doesn't settle too fast. For example, if you want to show a loading indicator for at least 1 second (but longer if needed) to prevent a confusing flash in the UI.

Install
npm install p-suite
Usage
import pMinDelay from 'p-suite/p-min-delay';

// With a promise
const value = await pMinDelay(somePromise, 1000);
// Executed after minimum 1 second even if `somePromise` fulfills before that

// With a function
const delayedFunction = pMinDelay(async () => {
	const result = await fetch('/api/data');
	return result.json();
}, 1000);

// The returned function will ensure a minimum delay
const data = await delayedFunction();
// Executed after minimum 1 second even if the fetch completes before that
API
pMinDelay(input, minimumDelay, options?)
input

Type: Promise | Function

Promise to delay or function to wrap with a delay.

When a function is passed, pMinDelay returns a new function that wraps the original. Each call to the returned function will ensure the promise it returns takes at least the specified minimum delay to settle.

minimumDelay

Type: number

Time in milliseconds.

see the rest of the docs in the source package

p-try

Documenation from source package | Back to packages

Start a promise chain

How is it useful?

Install
npm install p-suite
Usage
import pTry from 'p-suite/p-try';

try {
	const value = await pTry(() => {
		return synchronousFunctionThatMightThrow();
	});
	console.log(value);
} catch (error) {
	console.error(error);
}
API
pTry(fn, ...arguments)

Returns a Promise resolved with the value of calling fn(...arguments). If the function throws an error, the returned Promise will be rejected with that error.

Support for passing arguments on to the fn is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a lot of functions.

fn

The function to run to start the promise chain.

arguments

Arguments to pass to fn.

Related

p-race

Documenation from source package | Back to packages

A better Promise.race()

Improvements:

  • Fixes the silly behavior of Promise.race() returning a forever pending promise when supplied an empty iterable, which could create some really hard to debug problems. Promise.race() returns the first promise to fulfill or reject. Check out p-any if you like to get the first promise to fulfill.
  • Supports aborting promises using AbortSignal.
Install
npm install p-suite
Usage
import pRace from 'p-suite/p-race';

Promise.race([]);
// Returns a forever pending promise…

pRace([]);
//=> [RangeError: Expected the input to contain at least one item]
API
pRace(iterable | executor)
iterable

Type: Iterable<Promise | unknown>

executor

Type: signal => Iterable<Promise | unknown>

signal

Type: AbortSignal

You can pass the signal to each iterable's element to abort remaining promises when resolve the first promise.

Requires Node.js 16 or later.

import pRace from 'p-suite/p-race';

pRace(signal => [fetch('/api', {signal}), setTimeout(10, {signal})]);
// Remaining promises other than first one will be aborted.

see the rest of the docs in the source package

p-immediate

Documenation from source package | Back to packages

Returns a promise resolved in the next event loop - think setImmediate()

Promises are by default resolved in a microtask (current event loop).

Install
$ npm install p-suite
Usage
import pImmediate from 'p-suite/p-immediate';

await pImmediate();

// Executed in the next event loop
console.log('🦄');
Related
  • delay - Delay a promise a specified amount of time
  • p-min-delay - Delay a promise a minimum amount of time
  • p-timeout - Timeout a promise after a specified amount of time
  • More…

p-time

Documenation from source package | Back to packages

Measure the time a promise takes to resolve

Install
npm install p-suite
Usage
import pTime from 'p-suite/p-time';
import {execa} from 'execa';

const promise = pTime(execa)('sleep', ['1']);

await promise;
console.log(promise.time);
//=> 1016
API
pTime(asyncFunction)

Returns a decorated version of asyncFunction that when called returns a Promise with a time property of the elapsed time in milliseconds.

pTime.log(asyncFunction)

Returns a decorated version of asyncFunction that when called logs the elapsed time in milliseconds of the Promise.

asyncFunction

Type: Function

Promise-returning/async function.

Related

p-defer

Documenation from source package | Back to packages

Create a deferred promise

Don't use this unless you know what you're doing. Prefer the Promise constructor.

Install
npm install p-suite
Usage
import pDefer from 'p-suite/p-defer';

function delay(milliseconds) {
	const deferred = pDefer();
	setTimeout(deferred.resolve, milliseconds, '🦄');
	return deferred.promise;
}

console.log(await delay(100));
//=> '🦄'

The above is just an example. Use delay if you need to delay a promise.

API
pDefer()

Returns an object with a promise property and functions to resolve() and reject().

Related
  • p-lazy - Create a lazy promise that defers execution until .then() or .catch() is called
  • More…

p-is-promise

Documenation from source package | Back to packages

Check if something is a promise

Why not is-promise? That module checks for a thenable, not an ES2015 promise. This one is stricter.

You most likely don't need this. Just pass your value to Promise.resolve() and let it handle it.

Can be useful if you need to create a fast path for a synchronous operation.

Install
$ npm install p-suite
Usage
import isPromise from 'p-suite/p-is-promise';
import Bluebird from 'bluebird';

isPromise(Promise.resolve('🦄'));
//=> true

isPromise(Bluebird.resolve('🦄'));
//=> true

isPromise('🦄');
//=> false
Related

p-state

Documenation from source package | Back to packages

Inspect the state of a promise

You would usually not need this as you can just await the promise at any time to get its value even after it's resolved. This package could be useful if you need to check the state of the p