p-limit vs async vs bluebird vs promise-limit vs promise-queue
JavaScript Promise 和异步控制
p-limitasyncbluebirdpromise-limitpromise-queue类似的npm包:
JavaScript Promise 和异步控制

这些库提供了对 JavaScript 中异步操作的不同控制和优化方式。它们各自具有独特的功能,适用于不同的场景。async 是一个功能全面的库,提供了多种异步控制流工具,如并行、串行和限流。bluebird 是一个高性能的 Promise 库,提供了丰富的功能,如并发限制、错误处理和性能优化。p-limit 是一个轻量级的库,专注于限制并发 Promise 的数量,适用于需要简单限流的场景。promise-limit 提供了类似的功能,但更注重 API 的简洁性。promise-queue 是一个专注于队列管理的库,确保 Promise 按照特定顺序执行,适合需要严格顺序的异步操作。

npm下载趋势
3 年
GitHub Stars 排名
统计详情
npm包名称
下载量
Stars
大小
Issues
发布时间
License
p-limit180,627,2712,70211.7 kB52 个月前MIT
async73,829,58528,218808 kB221 年前MIT
bluebird35,363,20920,769-1276 年前MIT
promise-limit1,094,323143-107 年前ISC
promise-queue962,603230-108 年前MIT
功能对比: p-limit vs async vs bluebird vs promise-limit vs promise-queue

并发控制

  • p-limit:

    p-limit 允许开发者设置并发 Promise 的最大数量,简单易用,适合需要快速限流的场景。

  • async:

    async 提供了多种并发控制机制,如 async.parallelasync.seriesasync.eachLimit,支持灵活的并发和串行执行。

  • bluebird:

    bluebird 通过 Promise.mapPromise.each 提供并发限制功能,允许开发者指定并发数量,适合处理大量异步操作。

  • promise-limit:

    promise-limit 提供类似的并发限制功能,API 简洁,易于集成。

  • promise-queue:

    promise-queue 通过队列管理确保 Promise 按照顺序执行,适合需要严格控制执行顺序的场景。

错误处理

  • p-limit:

    p-limit 错误处理依赖于 Promise 的原生机制,简单直接。

  • async:

    async 提供了灵活的错误处理机制,支持回调函数中的错误传递,适合复杂的异步流程。

  • bluebird:

    bluebird 提供了强大的错误处理功能,支持链式捕获和自定义错误处理,性能优越。

  • promise-limit:

    promise-limit 也依赖于原生 Promise 错误处理,设计简洁。

  • promise-queue:

    promise-queue 通过队列管理错误,确保错误按照执行顺序处理。

性能

  • p-limit:

    p-limit 由于其轻量级设计,性能开销很小,适合需要高效限流的场景。

  • async:

    async 的性能开销主要来自于其丰富的功能和灵活性,适合对性能要求不是特别苛刻的场景。

  • bluebird:

    bluebird 是一个高性能的 Promise 实现,特别是在处理大量异步操作时,性能优势明显。

  • promise-limit:

    promise-limit 性能开销也很小,适合对性能要求较高的应用。

  • promise-queue:

    promise-queue 通过队列管理执行,性能开销主要来自于队列管理,但整体影响较小。

示例代码

  • p-limit:

    使用 p-limit 限制并发

    const pLimit = require('p-limit');
    const limit = pLimit(2);
    
    const tasks = [
      () => new Promise(resolve => setTimeout(() => resolve(1), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(2), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(3), 1000)),
    ];
    
    const limitedTasks = tasks.map(task => limit(task));
    Promise.all(limitedTasks).then(console.log);
    
  • async:

    使用 async 进行并发控制

    const async = require('async');
    
    async.eachLimit([1, 2, 3, 4], 2, (item, callback) => {
      setTimeout(() => {
        console.log(item);
        callback();
      }, 1000);
    });
    
  • bluebird:

    使用 bluebird 进行并发限制

    const Promise = require('bluebird');
    
    const tasks = [
      () => new Promise(resolve => setTimeout(() => resolve(1), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(2), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(3), 1000)),
    ];
    
    Promise.map(tasks, task => task(), { concurrency: 2 }).then(console.log);
    
  • promise-limit:

    使用 promise-limit 限制并发

    const limit = require('promise-limit')(2);
    
    const tasks = [
      () => new Promise(resolve => setTimeout(() => resolve(1), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(2), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(3), 1000)),
    ];
    
    const limitedTasks = tasks.map(task => limit(task));
    Promise.all(limitedTasks).then(console.log);
    
  • promise-queue:

    使用 promise-queue 确保顺序执行

    const Queue = require('promise-queue');
    const queue = new Queue(1); // 1 表示串行执行
    
    const tasks = [
      () => new Promise(resolve => setTimeout(() => resolve(1), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(2), 1000)),
      () => new Promise(resolve => setTimeout(() => resolve(3), 1000)),
    ];
    
    const queuedTasks = tasks.map(task => queue.add(task));
    Promise.all(queuedTasks).then(console.log);
    
如何选择: p-limit vs async vs bluebird vs promise-limit vs promise-queue
  • p-limit:

    选择 p-limit 如果您只需要限制并发 Promise 的数量,且希望保持库的轻量和简单。

  • async:

    选择 async 如果您需要一个功能全面的库,提供多种异步控制流工具,适用于复杂的异步操作和流程管理。

  • bluebird:

    选择 bluebird 如果您需要一个高性能的 Promise 实现,具有丰富的功能和优化,特别是在处理大量异步操作时。

  • promise-limit:

    选择 promise-limit 如果您需要一个简单易用的限流库,且不需要额外的功能。

  • promise-queue:

    选择 promise-queue 如果您需要确保 Promise 按照特定顺序执行,适合需要严格控制执行顺序的场景。

p-limit的README

p-limit

Run multiple promise-returning & async functions with limited concurrency

Works in Node.js and browsers.

Install

npm install p-limit

Usage

import pLimit from '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
Minimum: 1

Concurrency limit.

limit(fn, ...args)

Returns the promise returned by calling fn(...args).

fn

Type: Function

Promise-returning/async function.

args

Any arguments to pass through to fn.

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.

limit.map(iterable, mapperFunction)

Process an iterable of inputs with limited concurrency.

The mapper function receives the item value and its index.

Returns a promise equivalent to Promise.all(Array.from(iterable, (item, index) => limit(mapperFunction, item, index))).

This is a convenience function for processing inputs that arrive in batches. For more complex use cases, see p-map.

limit.activeCount

The number of promises that are currently running.

limit.pendingCount

The number of promises that are waiting to run (i.e. their internal fn was not called yet).

limit.clearQueue()

Discard pending promises that are waiting to run.

This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.

Note: This does not cancel promises that are already running.

limit.concurrency

Get or set the concurrency limit.

limitFunction(fn, options) named export

Returns a function with limited concurrency.

The returned function manages its own concurrent executions, allowing you to call it multiple times without exceeding the specified concurrency limit.

Ideal for scenarios where you need to control the number of simultaneous executions of a single function, rather than managing concurrency across multiple functions.

import {limitFunction} from 'p-limit';

const limitedFunction = limitFunction(async () => {
	return doSomething();
}, {concurrency: 1});

const input = Array.from({length: 10}, limitedFunction);

// Only one promise is run at once.
await Promise.all(input);

fn

Type: Function

Promise-returning/async function.

options

Type: object

concurrency

Type: number
Minimum: 1

Concurrency limit.

FAQ

How is this different from the p-queue package?

This package is only about limiting the number of concurrent executions, while p-queue is a fully featured queue implementation with lots of different options, introspection, and ability to pause the queue.

Related

  • p-throttle - Throttle promise-returning & async functions
  • p-debounce - Debounce promise-returning & async functions
  • p-map - Run promise-returning & async functions concurrently with different inputs
  • p-all - Run promise-returning & async functions concurrently with optional limited concurrency
  • More…