p-map vs bluebird
JavaScript Promise Libraries Comparison
1 Year
p-mapbluebirdSimilar Packages:
What's JavaScript Promise Libraries?

In the realm of JavaScript, managing asynchronous operations is crucial for building responsive applications. Libraries like Bluebird and p-map enhance the native Promise functionality, providing developers with powerful tools for handling concurrency and improving code readability. Bluebird is a fully-featured Promise library that offers advanced features such as cancellation, progress reporting, and a rich API for managing complex asynchronous flows. On the other hand, p-map is a utility for mapping over an array of values asynchronously, allowing for controlled concurrency, which is particularly useful when dealing with a large number of asynchronous operations that need to be executed in parallel without overwhelming the system.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
p-map47,263,4001,40621.2 kB123 months agoMIT
bluebird29,670,54020,449-1225 years agoMIT
Feature Comparison: p-map vs bluebird

Concurrency Control

  • p-map:

    p-map is specifically designed for controlled concurrency. It allows you to set a concurrency limit when mapping over an array, ensuring that only a specified number of promises are executed at once. This is particularly useful for tasks like making API calls where you want to avoid overwhelming the server.

  • bluebird:

    Bluebird provides a robust mechanism for handling concurrency through its Promise.map method, which allows you to control the number of concurrent operations. You can specify a concurrency limit, making it easy to manage resource usage when dealing with multiple asynchronous tasks.

Feature Set

  • p-map:

    p-map is a focused utility that provides a simple API for mapping over arrays asynchronously. It does not have the extensive feature set of Bluebird but excels in its specific use case of controlled concurrency, making it lightweight and easy to use.

  • bluebird:

    Bluebird comes with a rich set of features beyond basic Promise functionality, including cancellation, progress reporting, and various utility methods for working with collections of Promises. It also offers performance optimizations, making it a powerful choice for complex applications.

Error Handling

  • p-map:

    p-map relies on native Promise error handling. While it does not introduce additional error handling features, it allows you to handle errors in the same way as native Promises, making it straightforward for developers familiar with standard Promise behavior.

  • bluebird:

    Bluebird enhances error handling by providing a more intuitive way to catch and handle errors in asynchronous code. It supports chaining and allows for more granular control over error propagation, making it easier to manage complex error scenarios.

Performance

  • p-map:

    p-map is lightweight and optimized for its specific use case of mapping with controlled concurrency. While it may not have the extensive performance optimizations of Bluebird, it is efficient for its intended purpose, making it suitable for tasks that require limited concurrency.

  • bluebird:

    Bluebird is optimized for performance and can outperform native Promises in many scenarios, especially when dealing with a large number of asynchronous operations. Its internal optimizations and advanced features contribute to better performance in complex applications.

Learning Curve

  • p-map:

    p-map is straightforward and easy to learn, making it accessible for developers who need a simple solution for controlled concurrency. Its API is minimalistic, allowing for quick adoption without a steep learning curve.

  • bluebird:

    Bluebird has a steeper learning curve due to its extensive feature set and advanced capabilities. Developers may need to invest time to fully understand and leverage its functionalities, especially in complex scenarios.

How to Choose: p-map vs bluebird
  • p-map:

    Choose p-map if your primary requirement is to map over an array of items asynchronously with controlled concurrency. It is lightweight and straightforward, making it perfect for tasks like API requests where you want to limit the number of concurrent operations.

  • bluebird:

    Choose Bluebird if you need a comprehensive Promise library with advanced features like cancellation, progress tracking, and an extensive set of utility methods for working with Promises. It is ideal for complex asynchronous workflows and scenarios where performance optimization is critical.

README for p-map

p-map

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-map

Usage

import pMap from '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-map';

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

input

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

Synchronous or asynchronous iterable that is iterated over concurrently, calling the mapper function for each element. Each iterated item is await'd before the mapper is invoked so the iterable may return a Promise that resolves to an item.

Asynchronous iterables (different from synchronous iterables that return Promise that resolves to an item) can be used when the next item may not be ready without waiting for an asynchronous process to complete and/or the end of the iterable may be reached after the asynchronous process completes. For example, reading from a remote queue when the queue has reached empty, or reading lines from a stream.

mapper(element, index)

Type: Function

Expected to return a Promise or value.

options

Type: object

concurrency

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

Number of concurrently pending promises returned by mapper.

backpressure

Only for pMapIterable

Type: number (Integer)
Default: options.concurrency
Minimum: options.concurrency

Maximum number of promises returned by mapper that have resolved but not yet collected by the consumer of the async iterable. Calls to mapper will be limited so that there is never too much backpressure.

Useful whenever you are consuming the iterable slower than what the mapper function can produce concurrently. For example, to avoid making an overwhelming number of HTTP requests if you are saving each of the results to a database.

stopOnError

Only for pMap

Type: boolean
Default: true

When true, the first mapper rejection will be rejected back to the consumer.

When false, instead of stopping when a promise rejects, it will wait for all the promises to settle and then reject with an AggregateError containing all the errors from the rejected promises.

Caveat: When true, any already-started async mappers will continue to run until they resolve or reject. In the case of infinite concurrency with sync iterables, all mappers are invoked on startup and will continue after the first rejection. Issue #51 can be implemented for abort control.

signal

Only for pMap

Type: AbortSignal

You can abort the promises using AbortController.

import pMap from 'p-map';
import delay from 'delay';

const abortController = new AbortController();

setTimeout(() => {
	abortController.abort();
}, 500);

const mapper = async value => value;

await pMap([delay(1000), delay(1000)], mapper, {signal: abortController.signal});
// Throws AbortError (DOMException) after 500 ms.

pMapSkip

Return this value from a mapper function to skip including the value in the returned array.

import pMap, {pMapSkip} from 'p-map';
import got from 'got';

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

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

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

console.log(result);
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']

Related

  • p-all - Run promise-returning & async functions concurrently with optional limited concurrency
  • p-filter - Filter promises concurrently
  • p-times - Run promise-returning & async functions a specific number of times concurrently
  • p-props - Like Promise.all() but for Map and Object
  • p-map-series - Map over promises serially
  • More…