question
It is required to write a method to control the number of Promise concurrency, as follows:
promiseConcurrencyLimit(limit, array, iteratorFn)
limit is the number of promises executed at the same time, array is the parameter array, and iteratorFn is the asynchronous operation performed in each promise.
background
During development, post-logic logic needs to be executed after multiple promises are processed, usually using:
([p1, p2, p3]).then((res) => ...)
But there is a problem, because promises will be executed immediately after they are created, that is, multiple promise instances passed into , have already started to be executed when they are created . If the asynchronous operations performed in these instances are http requests, then n http requests will be issued in an instant, which is obviously unreasonable; a more reasonable way is: limit the number of asynchronous operations performed in , and only limit asynchronous operations are allowed to be executed at the same time at the same time.
Ideas & Implementation
In the background, the promise will be executed immediately after it is created, so the core of controlling concurrency is to control the generation of promise instances. At the beginning, only limit promise instances are generated, and then wait for these promise states to change. As long as the state of one of the promise instances changes, another promise instance will be created immediately... This loop is until all promises are created and executed.
There are many libraries on npm that implement this function. I personally think that the tiny-async-pool library is better because it directly uses the native Promise to implement this function, while most other libraries have re-implemented promises. Its core code is as follows:
async function asyncPool(poolLimit, array, iteratorFn) { const ret = []; // Used to store all promise instances const executing = []; // Used to store promises currently being executed for (const item of array) { const p = (iteratorFn(item)); // Prevent the callback function from returning not promise, use it to wrap (p); if (poolLimit <= ) { // Then in the callback, when the promise state becomes fulfilled, delete it from the execution promise list execution const e = (() => ((e), 1)); (e); if ( >= poolLimit) { // Once the number of promise lists being executed is equal to the limit, wait for a certain promise state to change. // After the status changes, the callback above will be executed and the promise will be deleted from the execution. // Then enter the next for loop and generate a new promise for replenishment await (executing); } } } return (ret); }
The test code is as follows:
const timeout = (i) => { ('start', i); return new Promise((resolve) => setTimeout(() => { resolve(i); ('Finish', i); }, i)); }; (async () => { const res = await asyncPool(2, [1000, 5000, 3000, 2000], timeout); (res); })();
The core idea of the code is:
- First initialize limit promise instances and place them in the executing array
- Use wait for the execution result of this limit promise instance
- Once the status of a promise changes, it is deleted from the execution, and then the loop is executed to generate a new promise and put it in the execution.
- Repeat steps 2 and 3 until all promises are executed
- Finally, use to return the execution results of all promise instances
This is the article about the method of js Promise concurrency control number. For more related js Promise concurrency control content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!