#2721. promiseAll Implementation
IntuitionThe problem requires us to execute a series of functions that each return a promise and collect the results of those promises into an array. The key ob
# Intuition

The problem requires us to execute a series of functions that each return a promise and collect the results of those promises into an array. The key observation is that we can create a new promise that resolves once all the input promises (generated from the functions) are resolved. The challenge is to handle the promises efficiently, ensuring that we wait for all of them before resolving the final result. We can accomplish this using a `Promise` and keep track of each promise's resolution using an array of results and a counter for how many promises have completed.

# Approach

To solve this problem:
1. **Iterate over the `functions` array**: Each function in the array returns a promise, so we will invoke each function to get the promise.
2. **Track the results**: For each promise, we store the resolved value in the corresponding index of an array (`results`).
3. **Track completion**: We maintain a counter (`completed`) to count how many promises have been resolved. Once all promises are resolved, we can resolve the final promise with the `results` array.
4. **Handle rejections**: If any of the promises rejects, we immediately reject the final promise with that error.
5. **Return a new Promise**: The function `promiseAll` returns a promise that resolves when all the promises are resolved, or rejects if any of them rejects.

The function uses the `Promise` constructor to manage the asynchronous behavior and ensures the order of results matches the order of input functions.

# Complexity

- **Time complexity**:  
  $$O(n)$$  
  We loop through all the functions in the array once, and for each function, we handle a promise resolution. Since each promise resolves in constant time, the overall time complexity is linear, relative to the number of functions (`n`).

- **Space complexity**:  
  $$O(n)$$  
  We store the results of each promise in an array, and thus we need space proportional to the number of functions. The space complexity is linear in terms of the number of functions (`n`).


# Code
```javascript []
/**
 * @param {Array<Function>} functions
 * @return {Promise<any>}
 */
var promiseAll = function(functions) {
    // Return a new promise
    return new Promise((resolve, reject) => {
        // Use an array to hold the results of each promise
        let results = [];
        let completed = 0;

        // Loop over the functions array
        functions.forEach((func, index) => {
            // Call the function to get the promise
            func().then(result => {
                // Store the result in the results array
                results[index] = result;
                completed++;

                // If all promises have been resolved, resolve the main promise with the results array
                if (completed === functions.length) {
                    resolve(results);
                }
            }).catch(err => {
                // If any promise rejects, reject the main promise with the error
                reject(err);
            });
        });
    });
};

/**
 * Example usage:
 * const promise = promiseAll([() => new Promise(res => res(42)), () => new Promise(res => res(36))]);
 * promise.then(console.log); // [42, 36]
 */

```
['JavaScript']