Promise Pool JavaScript Leetcode 2636

Hi there, I am Ujjawal, programmer with a keen interest in problem-solving and developing new software that will add value to the community.
As a software developer, my goal is to build solutions that can make human life easier in any way possible.
My current skillset includes :
- C/C++
- Data Structures & Algorithms
- Database Management
- HTML5, CSS3, JavaScript.
- Frameworks/Libraries like React, Tailwind CSS, Bootstrap
I am always ready to learn new technologies and implement them to current solutions to make them more efficient and robust.
Given an array of asynchronous functions functions and a pool limit n, return an asynchronous function promisePool. It should return a promise that resolves when all the input functions resolve.
The Pool limit is defined as the maximum number of promises that can be pending at once. promisePool should begin execution of as many functions as possible and continue executing new functions when old promises resolve. promisePool should execute functions[i] then functions[i + 1] then functions[i+2], etc. When the last promise resolves, promisePool should also resolve.
For example, if n = 1, promisePool will execute one function at a time in a series. However, if n = 2, it first executes two functions. When either of the two functions resolves, a 3rd function should be executed (if available), and so on until there are no functions left to execute.
You can assume all functions never reject. It is acceptable for promisePool to return a promise that resolves any value.
Example 1:
Input:
functions = [
() => new Promise(res => setTimeout(res, 300)),
() => new Promise(res => setTimeout(res, 400)),
() => new Promise(res => setTimeout(res, 200))
]
n = 2
Output: [[300, 400, 500],500]
Explanation:
Three functions are passed in. They sleep for 300ms, 400ms, and 200ms respectively.
They resolve at 300ms, 400ms, and 500ms respectively. The returned promise resolves at 500ms.
At t=0, the first 2 functions are executed. The pool size limit of 2 is reached.
At t=300, the 1st function resolves, and the 3rd function is executed. The pool size is 2.
At t=400, the 2nd function resolves. There is nothing left to execute. The pool size is 1.
At t=500, the 3rd function resolves. The pool size is 0 so the returned promise also resolves.
Example 2:
Input:
functions = [
() => new Promise(res => setTimeout(res, 300)),
() => new Promise(res => setTimeout(res, 400)),
() => new Promise(res => setTimeout(res, 200))
]
n = 5
Output: [[300, 400, 200], 400]
Explanation:
The three input promises resolve at 300ms, 400ms, and 200ms respectively.
The returned promise resolves at 400ms.
At t=0, all 3 functions are executed. The pool limit of 5 is never met.
At t=200, the 3rd function resolves. The pool size is 2.
At t=300, the 1st function resolved. The pool size is 1.
At t=400, the 2nd function resolves. The pool size is 0, so the returned promise also resolves.
Example 3:
Input:
functions = [
() => new Promise(res => setTimeout(res, 300)),
() => new Promise(res => setTimeout(res, 400)),
() => new Promise(res => setTimeout(res, 200))
]
n = 1
Output: [[300,700,9001,900]
Explanation:
The three input promises resolve at 300ms, 700ms, and 900ms respectively. The returned promise resolves at 900ms.
At t=0, the 1st function is executed. The pool size is 1.
At t=300, the 1st function resolves and the 2nd function is executed. The pool size is 1.
At t=700, the 2nd function resolves and the 3rd function is executed. The pool size is 1.
At t=900, the 3rd function resolves. The pool size is 0 so the returned promise resolves.
Constraints:
0 <= function.length <= 10
0 <= n <= 10
Intuition:
The problem revolves around executing a given set of asynchronous functions in a controlled manner with a specified pool limit. The goal is to execute as many functions concurrently as the pool limit allows while ensuring that the overall execution sequence follows the order of the input functions.
Approach:
The
promisePoolfunction is defined with two parameters: an array of asynchronous functionsfunctionsand an integernrepresenting the pool limit.The function returns a
Promise. It's an asynchronous function that takes advantage of theasync/awaitsyntax and usesPromisefor its asynchronous operations.Inside the returned
Promise, ahelperfunction is defined. This function is responsible for managing the execution of functions and the pool size.The base case of the recursion is checked: If the
indexis greater than or equal to the length offunctionsand there are no promises in progress (inProgress === 0), it means all functions have been executed. In this case, the main promise is resolved to signal the completion.Inside the
helperfunction, awhileloop is used to execute functions in parallel up to the pool limitn. It checks if there's room in the pool (inProgress < n) and if there are more functions to execute (index < functions.length).When the loop condition is met, the
inProgresscounter is incremented, and the current function at theindexis executed using.then(). When the promise of the function resolves, theinProgresscounter is decremented, and thehelperfunction is called recursively. This ensures that as soon as one function completes, another function is started.Outside the
helperfunction, the execution is initiated by calling thehelperfunction for the first time.
Code:
/**
* @param {Function[]} functions
* @param {number} n
* @return {Function}
*/
// TC: O(functions.length)
var promisePool = async function (functions, n) {
return new Promise((resolve) => {
let inProgress = 0, index = 0;
function helper() {
// base case
if (index >= functions.length) {
if (inProgress === 0) resolve();
return;
}
while (inProgress < n && index < functions.length) {
inProgress++;
functions[index++]().then(() => {
inProgress--;
helper();
});
}
}
helper();
});
};
/**
* const sleep = (t) => new Promise(res => setTimeout(res, t));
* promisePool([() => sleep(500), () => sleep(400)], 1)
* .then(console.log) // After 900ms
*/
Time Complexity:
The time complexity of this code is O(functions.length), where "functions.length" represents the number of functions in the input array. This is because each function is executed once within the while loop, and the while loop iterates through all the functions in the array.
Space Complexity:
The space complexity of this code is O(1), which is constant space complexity. This is because the memory usage of the code does not grow with the input size or any recursion depth.
Checkout the video Solution:
Hope you find helpful, if yes then give it a like.



