0
# p-limit
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: p-limit
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install p-limit`
10
11
## Core Imports
12
13
```javascript
14
import pLimit from 'p-limit';
15
```
16
17
For named import:
18
19
```javascript
20
import { limitFunction } from 'p-limit';
21
```
22
23
Combined import:
24
25
```javascript
26
import pLimit, { limitFunction } from 'p-limit';
27
```
28
29
For CommonJS:
30
31
```javascript
32
const pLimit = require('p-limit');
33
const { limitFunction } = require('p-limit');
34
```
35
36
## Basic Usage
37
38
```javascript
39
import pLimit from 'p-limit';
40
41
const limit = pLimit(2);
42
43
const input = [
44
limit(() => fetchSomething('foo')),
45
limit(() => fetchSomething('bar')),
46
limit(() => doSomething()),
47
limit(() => doAnotherThing())
48
];
49
50
// Only two promises run at once
51
const result = await Promise.all(input);
52
console.log(result);
53
```
54
55
## Architecture
56
57
p-limit is built around a simple concurrency control pattern:
58
59
- **Limit Function**: The core `pLimit()` factory creates a limit function that manages concurrency
60
- **Internal Queue**: Uses `yocto-queue` for efficient FIFO promise queuing
61
- **Active Tracking**: Monitors currently running promises vs. concurrency limit
62
- **Dynamic Control**: Supports runtime adjustment of concurrency limits
63
- **Context Preservation**: Maintains async execution context throughout operations
64
65
## Capabilities
66
67
### Core Concurrency Control
68
69
Create a limit function that restricts the number of simultaneously executing promises.
70
71
```javascript { .api }
72
/**
73
* Run multiple promise-returning & async functions with limited concurrency
74
* @param concurrency - Concurrency limit. Minimum: 1
75
* @returns A limit function
76
*/
77
function pLimit(concurrency: number): LimitFunction;
78
```
79
80
**Usage Example:**
81
82
```javascript
83
import pLimit from 'p-limit';
84
85
const limit = pLimit(3);
86
87
// Execute with concurrency limit
88
const promises = [
89
limit(() => fetch('/api/user/1')),
90
limit(() => fetch('/api/user/2')),
91
limit(() => fetch('/api/user/3')),
92
limit(() => fetch('/api/user/4')), // Will wait for one of above to complete
93
];
94
95
const results = await Promise.all(promises);
96
```
97
98
### Function Execution
99
100
Execute promise-returning or async functions with the concurrency limit.
101
102
```javascript { .api }
103
/**
104
* Execute a function with concurrency control
105
* @param fn - Promise-returning/async function
106
* @param arguments - Any arguments to pass through to fn
107
* @returns The promise returned by calling fn(...arguments)
108
*/
109
<Arguments extends unknown[], ReturnType>(
110
function_: (...arguments_: Arguments) => PromiseLike<ReturnType> | ReturnType,
111
...arguments_: Arguments
112
): Promise<ReturnType>;
113
```
114
115
**Usage Example:**
116
117
```javascript
118
const limit = pLimit(2);
119
120
// Pass arguments to the limited function
121
const result1 = await limit(processData, dataSet1, options);
122
const result2 = await limit(processData, dataSet2, options);
123
```
124
125
### Active Count Monitoring
126
127
Monitor the number of currently running promises.
128
129
```javascript { .api }
130
/**
131
* The number of promises that are currently running
132
*/
133
readonly activeCount: number;
134
```
135
136
**Usage Example:**
137
138
```javascript
139
const limit = pLimit(3);
140
141
limit(() => delay(1000));
142
limit(() => delay(1000));
143
144
console.log(limit.activeCount); // 2
145
```
146
147
### Pending Count Monitoring
148
149
Monitor the number of promises waiting to run.
150
151
```javascript { .api }
152
/**
153
* The number of promises that are waiting to run (i.e. their internal fn was not called yet)
154
*/
155
readonly pendingCount: number;
156
```
157
158
**Usage Example:**
159
160
```javascript
161
const limit = pLimit(2);
162
163
// Queue 5 promises, 2 will run immediately, 3 will be pending
164
Array.from({length: 5}, () => limit(() => delay(1000)));
165
166
console.log(limit.activeCount); // 2
167
console.log(limit.pendingCount); // 3
168
```
169
170
### Dynamic Concurrency Control
171
172
Get or set the concurrency limit at runtime.
173
174
```javascript { .api }
175
/**
176
* Get or set the concurrency limit
177
*/
178
concurrency: number;
179
```
180
181
**Usage Example:**
182
183
```javascript
184
const limit = pLimit(2);
185
186
console.log(limit.concurrency); // 2
187
188
// Increase concurrency at runtime
189
limit.concurrency = 5;
190
191
// This will immediately start more pending promises if available
192
```
193
194
### Queue Management
195
196
Clear pending promises that are waiting to run.
197
198
```javascript { .api }
199
/**
200
* Discard pending promises that are waiting to run.
201
* Note: This does not cancel promises that are already running.
202
*/
203
clearQueue(): void;
204
```
205
206
**Usage Example:**
207
208
```javascript
209
const limit = pLimit(1);
210
211
// Queue multiple operations
212
limit(() => delay(1000));
213
limit(() => delay(1000));
214
limit(() => delay(1000));
215
216
console.log(limit.pendingCount); // 2
217
218
limit.clearQueue();
219
220
console.log(limit.pendingCount); // 0
221
```
222
223
### Array Processing
224
225
Process an array of inputs with limited concurrency using a mapper function.
226
227
```javascript { .api }
228
/**
229
* Process an array of inputs with limited concurrency
230
* @param array - An array containing arguments for the mapper function
231
* @param mapperFunction - Promise-returning/async function that processes each item
232
* @returns A Promise that returns an array of results
233
*/
234
map<Input, ReturnType>(
235
array: readonly Input[],
236
mapperFunction: (input: Input, index: number) => PromiseLike<ReturnType> | ReturnType
237
): Promise<ReturnType[]>;
238
```
239
240
**Usage Example:**
241
242
```javascript
243
const limit = pLimit(3);
244
245
const results = await limit.map([1, 2, 3, 4, 5], async (number, index) => {
246
await delay(100);
247
return number * 2;
248
});
249
250
console.log(results); // [2, 4, 6, 8, 10]
251
```
252
253
### Function Wrapper
254
255
Create a function with built-in concurrency limiting for repeated use.
256
257
```javascript { .api }
258
/**
259
* Returns a function with limited concurrency
260
* @param function_ - Promise-returning/async function
261
* @param options - Configuration object with concurrency property
262
* @returns Function with limited concurrency
263
*/
264
function limitFunction<Arguments extends unknown[], ReturnType>(
265
function_: (...arguments_: Arguments) => PromiseLike<ReturnType>,
266
options: Options
267
): (...arguments_: Arguments) => Promise<ReturnType>;
268
```
269
270
**Usage Example:**
271
272
```javascript
273
import { limitFunction } from 'p-limit';
274
275
const limitedFetch = limitFunction(async (url) => {
276
const response = await fetch(url);
277
return response.json();
278
}, { concurrency: 2 });
279
280
// These calls will be limited to 2 concurrent executions
281
const results = await Promise.all([
282
limitedFetch('/api/data/1'),
283
limitedFetch('/api/data/2'),
284
limitedFetch('/api/data/3'),
285
limitedFetch('/api/data/4'),
286
]);
287
```
288
289
## Types
290
291
```javascript { .api }
292
interface LimitFunction {
293
readonly activeCount: number;
294
readonly pendingCount: number;
295
concurrency: number;
296
clearQueue(): void;
297
map<Input, ReturnType>(
298
array: readonly Input[],
299
mapperFunction: (input: Input, index: number) => PromiseLike<ReturnType> | ReturnType
300
): Promise<ReturnType[]>;
301
<Arguments extends unknown[], ReturnType>(
302
function_: (...arguments_: Arguments) => PromiseLike<ReturnType> | ReturnType,
303
...arguments_: Arguments
304
): Promise<ReturnType>;
305
}
306
307
interface Options {
308
readonly concurrency: number;
309
}
310
```
311
312
## Error Handling
313
314
p-limit validates the concurrency parameter and throws meaningful errors:
315
316
```javascript
317
// Throws TypeError: Expected `concurrency` to be a number from 1 and up
318
pLimit(0); // Invalid: must be >= 1
319
pLimit(-1); // Invalid: must be positive
320
pLimit(1.5); // Invalid: must be integer
321
pLimit(null); // Invalid: must be number
322
```
323
324
p-limit preserves promise rejections from the original functions:
325
326
```javascript
327
const limit = pLimit(1);
328
329
try {
330
await limit(() => {
331
throw new Error('Function failed');
332
});
333
} catch (error) {
334
console.log(error.message); // 'Function failed'
335
}
336
```