Created
May 13, 2021 15:08
-
-
Save gerardolima/cf9e885dafa35d8225f5f17a7a38e6a3 to your computer and use it in GitHub Desktop.
This Gist demonstrates how to keep control a maximum of concurrent promises using standard NodeJs Promises.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const CONCURRENT_LIMIT = 3 | |
| const workUnits = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] | |
| /** Returns a Promise that resolves after `milliseconds` */ | |
| const sleep = (milliseconds = 1) => new Promise((resolve) => setTimeout(resolve, milliseconds)) | |
| /** Placeholder for any business-related async function */ | |
| const worker = async (id) => { | |
| console.log(`working on ${id}`) | |
| await sleep( 100 * Math.random() ) | |
| console.log(`${id} is completed`) | |
| } | |
| const poc = async() => { | |
| let semaphore = 0 | |
| for(const id of workUnits) { | |
| // wait for an available "slot" to run the worker | |
| while(semaphore >= CONCURRENT_LIMIT) { await sleep() } | |
| semaphore++ | |
| void worker(id).finally(() => semaphore--) | |
| } | |
| // wait all pending promises | |
| while(semaphore) { await sleep() } | |
| } | |
| poc() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code emerged from an atual problem, when I needed to use an asynchronous API a number of times, but this API had a limit of concurrent calls. Since the expected total number of API calls would be higher of the API concurrent calls limit, using
Promise.allSettled()was not an option. On the other side, usingwaiton each call would make all the waiting times cumulative, and that was not ideal.This code keeps at most
CONCURRENT_LIMITpending Promises at a time and waits then before making more asynchronous calls, until all theworkUnitsare processed.