Skip to content

Commit

Permalink
Add limitFunction() (#88)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <[email protected]>
liuhanqu and sindresorhus authored Dec 19, 2024

Verified

This commit was signed with the committer’s verified signature. The key has expired.
juliusknorr Julius Knorr
1 parent c7f7687 commit ef48184
Showing 4 changed files with 101 additions and 2 deletions.
38 changes: 38 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -41,3 +41,41 @@ Run multiple promise-returning & async functions with limited concurrency.
@returns A `limit` function.
*/
export default function pLimit(concurrency: number): LimitFunction;

export type Options = {
/**
Concurrency limit.
Minimum: `1`.
*/
readonly concurrency: number;
};

/**
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.
@param function_ - Promise-returning/async function.
@return Function with limited concurrency.
@example
```
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);
```
*/
export function limitFunction<Arguments extends unknown[], ReturnType>(
function_: (...arguments_: Arguments) => PromiseLike<ReturnType> | ReturnType,
option: Options
): (...arguments_: Arguments) => Promise<ReturnType>;
7 changes: 7 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -90,6 +90,13 @@ export default function pLimit(concurrency) {
return generator;
}

export function limitFunction(function_, option) {
const {concurrency} = option;
const limit = pLimit(concurrency);

return (...arguments_) => limit(() => function_(...arguments_));
}

function validateConcurrency(concurrency) {
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
40 changes: 39 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ console.log(result);

## API

### pLimit(concurrency)
### pLimit(concurrency) <sup>default export</sup>

Returns a `limit` function.

@@ -77,6 +77,44 @@ Note: This does not cancel promises that are already running.

Get or set the concurrency limit.

### limitFunction(fn, options) <sup>named export</sup>

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.

```js
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`](https://github.com/sindresorhus/p-queue) package?
18 changes: 17 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import delay from 'delay';
import inRange from 'in-range';
import timeSpan from 'time-span';
import randomInt from 'random-int';
import pLimit from './index.js';
import pLimit, {limitFunction} from './index.js';

test('concurrency: 1', async t => {
const input = [
@@ -217,3 +217,19 @@ test('change concurrency to bigger value', async t => {
await Promise.all(promises);
t.deepEqual(log, [1, 2, 3, 4, 4, 4, 4, 4, 4, 4]);
});

test('limitFunction()', async t => {
const concurrency = 5;
let running = 0;

const limitedFunction = limitFunction(async () => {
running++;
t.true(running <= concurrency);
await delay(randomInt(30, 200));
running--;
}, {concurrency});

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

await Promise.all(input);
});

0 comments on commit ef48184

Please sign in to comment.