+12
-0
@@ -27,2 +27,14 @@ export type LimitFunction = { | ||
| /** | ||
| Process an array of inputs with limited concurrency. | ||
| @param array - An array containing an argument for the given function. | ||
| @param function_ - Promise-returning/async function. | ||
| @returns A Promise that returns an array of results. | ||
| */ | ||
| map: <Input, ReturnType> ( | ||
| array: Input[], | ||
| function_: (input: Input) => PromiseLike<ReturnType> | ReturnType | ||
| ) => Promise<ReturnType[]>; | ||
| /** | ||
| @param fn - Promise-returning/async function. | ||
@@ -29,0 +41,0 @@ @param arguments - 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. |
+24
-22
@@ -10,6 +10,6 @@ import Queue from 'yocto-queue'; | ||
| const resumeNext = () => { | ||
| // Process the next queued function if we're under the concurrency limit | ||
| if (activeCount < concurrency && queue.size > 0) { | ||
| activeCount++; | ||
| queue.dequeue()(); | ||
| // Since `pendingCount` has been decreased by one, increase `activeCount` by one. | ||
| activeCount++; | ||
| } | ||
@@ -20,3 +20,2 @@ }; | ||
| activeCount--; | ||
| resumeNext(); | ||
@@ -26,6 +25,11 @@ }; | ||
| const run = async (function_, resolve, arguments_) => { | ||
| // Execute the function and capture the result promise | ||
| const result = (async () => function_(...arguments_))(); | ||
| // Resolve immediately with the promise (don't wait for completion) | ||
| resolve(result); | ||
| // Wait for the function to complete (success or failure) | ||
| // We catch errors here to prevent unhandled rejections, | ||
| // but the original promise rejection is preserved for the caller | ||
| try { | ||
@@ -35,2 +39,3 @@ await result; | ||
| // Decrement active count and process next queued function | ||
| next(); | ||
@@ -40,21 +45,12 @@ }; | ||
| const enqueue = (function_, resolve, arguments_) => { | ||
| // Queue `internalResolve` instead of the `run` function | ||
| // to preserve asynchronous context. | ||
| new Promise(internalResolve => { | ||
| // Queue the internal resolve function instead of the run function | ||
| // to preserve the asynchronous execution context. | ||
| new Promise(internalResolve => { // eslint-disable-line promise/param-names | ||
| queue.enqueue(internalResolve); | ||
| }).then( | ||
| run.bind(undefined, function_, resolve, arguments_), | ||
| ); | ||
| }).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then | ||
| (async () => { | ||
| // This function needs to wait until the next microtask before comparing | ||
| // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously | ||
| // after the `internalResolve` function is dequeued and called. The comparison in the if-statement | ||
| // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. | ||
| await Promise.resolve(); | ||
| if (activeCount < concurrency) { | ||
| resumeNext(); | ||
| } | ||
| })(); | ||
| // Start processing immediately if we haven't reached the concurrency limit | ||
| if (activeCount < concurrency) { | ||
| resumeNext(); | ||
| } | ||
| }; | ||
@@ -93,2 +89,8 @@ | ||
| }, | ||
| map: { | ||
| async value(array, function_) { | ||
| const promises = array.map(value => this(function_, value)); | ||
| return Promise.all(promises); | ||
| }, | ||
| }, | ||
| }); | ||
@@ -99,4 +101,4 @@ | ||
| export function limitFunction(function_, option) { | ||
| const {concurrency} = option; | ||
| export function limitFunction(function_, options) { | ||
| const {concurrency} = options; | ||
| const limit = pLimit(concurrency); | ||
@@ -103,0 +105,0 @@ |
+8
-7
| { | ||
| "name": "p-limit", | ||
| "version": "6.2.0", | ||
| "version": "7.0.0", | ||
| "description": "Run multiple promise-returning & async functions with limited concurrency", | ||
@@ -20,6 +20,7 @@ "license": "MIT", | ||
| "engines": { | ||
| "node": ">=18" | ||
| "node": ">=20" | ||
| }, | ||
| "scripts": { | ||
| "test": "xo && ava && tsd" | ||
| "test": "xo && ava && tsd", | ||
| "benchmark": "node benchmark.js" | ||
| }, | ||
@@ -48,6 +49,6 @@ "files": [ | ||
| "dependencies": { | ||
| "yocto-queue": "^1.1.1" | ||
| "yocto-queue": "^1.2.1" | ||
| }, | ||
| "devDependencies": { | ||
| "ava": "^6.1.3", | ||
| "ava": "^6.4.1", | ||
| "delay": "^6.0.0", | ||
@@ -57,5 +58,5 @@ "in-range": "^3.0.0", | ||
| "time-span": "^5.1.0", | ||
| "tsd": "^0.31.1", | ||
| "xo": "^0.58.0" | ||
| "tsd": "^0.33.0", | ||
| "xo": "^1.2.1" | ||
| } | ||
| } |
+9
-0
@@ -60,2 +60,10 @@ # p-limit | ||
| ### limit.map(array, fn) | ||
| Process an array of inputs with limited concurrency. | ||
| Returns a promise equivalent to `Promise.all(array.map(item => limit(fn, item)))`. | ||
| This is a convenience function for processing inputs that arrive in batches. For more complex use cases, see [p-map](https://github.com/sindresorhus/p-map). | ||
| ### limit.activeCount | ||
@@ -129,3 +137,4 @@ | ||
| - [p-debounce](https://github.com/sindresorhus/p-debounce) - Debounce promise-returning & async functions | ||
| - [p-map](https://github.com/sindresorhus/p-map) - Run promise-returning & async functions concurrently with different inputs | ||
| - [p-all](https://github.com/sindresorhus/p-all) - Run promise-returning & async functions concurrently with optional limited concurrency | ||
| - [Moreā¦](https://github.com/sindresorhus/promise-fun) |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
11514
11.29%161
9.52%139
6.92%3
50%Updated