or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-p-limit

Run multiple promise-returning & async functions with limited concurrency

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/p-limit@7.1.x

To install, run

npx @tessl/cli install tessl/npm-p-limit@7.1.0

index.mddocs/

p-limit

p-limit provides concurrency control for JavaScript promises and async functions, enabling developers to limit the number of simultaneously executing asynchronous operations. It offers a simple API that wraps promise-returning functions with concurrency limits, preventing system overload and resource exhaustion when processing large batches of asynchronous tasks.

Package Information

  • Package Name: p-limit
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install p-limit

Core Imports

import pLimit from 'p-limit';

For named import:

import { limitFunction } from 'p-limit';

Combined import:

import pLimit, { limitFunction } from 'p-limit';

For CommonJS:

const pLimit = require('p-limit');
const { limitFunction } = require('p-limit');

Basic Usage

import pLimit from 'p-limit';

const limit = pLimit(2);

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

// Only two promises run at once
const result = await Promise.all(input);
console.log(result);

Architecture

p-limit is built around a simple concurrency control pattern:

  • Limit Function: The core pLimit() factory creates a limit function that manages concurrency
  • Internal Queue: Uses yocto-queue for efficient FIFO promise queuing
  • Active Tracking: Monitors currently running promises vs. concurrency limit
  • Dynamic Control: Supports runtime adjustment of concurrency limits
  • Context Preservation: Maintains async execution context throughout operations

Capabilities

Core Concurrency Control

Create a limit function that restricts the number of simultaneously executing promises.

/**
 * Run multiple promise-returning & async functions with limited concurrency
 * @param concurrency - Concurrency limit. Minimum: 1
 * @returns A limit function
 */
function pLimit(concurrency: number): LimitFunction;

Usage Example:

import pLimit from 'p-limit';

const limit = pLimit(3);

// Execute with concurrency limit
const promises = [
  limit(() => fetch('/api/user/1')),
  limit(() => fetch('/api/user/2')),
  limit(() => fetch('/api/user/3')),
  limit(() => fetch('/api/user/4')), // Will wait for one of above to complete
];

const results = await Promise.all(promises);

Function Execution

Execute promise-returning or async functions with the concurrency limit.

/**
 * Execute a function with concurrency control
 * @param fn - Promise-returning/async function
 * @param arguments - Any arguments to pass through to fn
 * @returns The promise returned by calling fn(...arguments)
 */
<Arguments extends unknown[], ReturnType>(
  function_: (...arguments_: Arguments) => PromiseLike<ReturnType> | ReturnType,
  ...arguments_: Arguments
): Promise<ReturnType>;

Usage Example:

const limit = pLimit(2);

// Pass arguments to the limited function
const result1 = await limit(processData, dataSet1, options);
const result2 = await limit(processData, dataSet2, options);

Active Count Monitoring

Monitor the number of currently running promises.

/**
 * The number of promises that are currently running
 */
readonly activeCount: number;

Usage Example:

const limit = pLimit(3);

limit(() => delay(1000));
limit(() => delay(1000));

console.log(limit.activeCount); // 2

Pending Count Monitoring

Monitor the number of promises waiting to run.

/**
 * The number of promises that are waiting to run (i.e. their internal fn was not called yet)
 */
readonly pendingCount: number;

Usage Example:

const limit = pLimit(2);

// Queue 5 promises, 2 will run immediately, 3 will be pending
Array.from({length: 5}, () => limit(() => delay(1000)));

console.log(limit.activeCount);  // 2
console.log(limit.pendingCount); // 3

Dynamic Concurrency Control

Get or set the concurrency limit at runtime.

/**
 * Get or set the concurrency limit
 */
concurrency: number;

Usage Example:

const limit = pLimit(2);

console.log(limit.concurrency); // 2

// Increase concurrency at runtime
limit.concurrency = 5;

// This will immediately start more pending promises if available

Queue Management

Clear pending promises that are waiting to run.

/**
 * Discard pending promises that are waiting to run.
 * Note: This does not cancel promises that are already running.
 */
clearQueue(): void;

Usage Example:

const limit = pLimit(1);

// Queue multiple operations
limit(() => delay(1000));
limit(() => delay(1000));
limit(() => delay(1000));

console.log(limit.pendingCount); // 2

limit.clearQueue();

console.log(limit.pendingCount); // 0

Array Processing

Process an array of inputs with limited concurrency using a mapper function.

/**
 * Process an array of inputs with limited concurrency
 * @param array - An array containing arguments for the mapper function
 * @param mapperFunction - Promise-returning/async function that processes each item
 * @returns A Promise that returns an array of results
 */
map<Input, ReturnType>(
  array: readonly Input[],
  mapperFunction: (input: Input, index: number) => PromiseLike<ReturnType> | ReturnType
): Promise<ReturnType[]>;

Usage Example:

const limit = pLimit(3);

const results = await limit.map([1, 2, 3, 4, 5], async (number, index) => {
  await delay(100);
  return number * 2;
});

console.log(results); // [2, 4, 6, 8, 10]

Function Wrapper

Create a function with built-in concurrency limiting for repeated use.

/**
 * Returns a function with limited concurrency
 * @param function_ - Promise-returning/async function
 * @param options - Configuration object with concurrency property
 * @returns Function with limited concurrency
 */
function limitFunction<Arguments extends unknown[], ReturnType>(
  function_: (...arguments_: Arguments) => PromiseLike<ReturnType>,
  options: Options
): (...arguments_: Arguments) => Promise<ReturnType>;

Usage Example:

import { limitFunction } from 'p-limit';

const limitedFetch = limitFunction(async (url) => {
  const response = await fetch(url);
  return response.json();
}, { concurrency: 2 });

// These calls will be limited to 2 concurrent executions
const results = await Promise.all([
  limitedFetch('/api/data/1'),
  limitedFetch('/api/data/2'),
  limitedFetch('/api/data/3'),
  limitedFetch('/api/data/4'),
]);

Types

interface LimitFunction {
  readonly activeCount: number;
  readonly pendingCount: number;
  concurrency: number;
  clearQueue(): void;
  map<Input, ReturnType>(
    array: readonly Input[],
    mapperFunction: (input: Input, index: number) => PromiseLike<ReturnType> | ReturnType
  ): Promise<ReturnType[]>;
  <Arguments extends unknown[], ReturnType>(
    function_: (...arguments_: Arguments) => PromiseLike<ReturnType> | ReturnType,
    ...arguments_: Arguments
  ): Promise<ReturnType>;
}

interface Options {
  readonly concurrency: number;
}

Error Handling

p-limit validates the concurrency parameter and throws meaningful errors:

// Throws TypeError: Expected `concurrency` to be a number from 1 and up
pLimit(0);     // Invalid: must be >= 1
pLimit(-1);    // Invalid: must be positive
pLimit(1.5);   // Invalid: must be integer
pLimit(null);  // Invalid: must be number

p-limit preserves promise rejections from the original functions:

const limit = pLimit(1);

try {
  await limit(() => {
    throw new Error('Function failed');
  });
} catch (error) {
  console.log(error.message); // 'Function failed'
}