Implement Promise.all
In JavaScript, Promise.all is a powerful utility for handling multiple asynchronous operations concurrently. It allows you to pass an iterable of Promises and returns a single Promise that resolves when all of the Promises in the iterable have resolved, or rejects as soon as one of the Promises rejects. This challenge asks you to re-implement this crucial functionality.
Problem Description
Your task is to create a function named myPromiseAll that mimics the behavior of Promise.all. This function should accept an iterable (e.g., an array) of Promises as its argument.
Requirements:
- The
myPromiseAllfunction should return a new Promise. - This returned Promise should resolve with an array of the resolved values from the input Promises, in the same order as the original iterable.
- If any of the input Promises reject, the returned Promise should immediately reject with the reason of the first Promise that rejected.
- If the input iterable is empty, the returned Promise should resolve immediately with an empty array.
- The function should handle non-Promise values within the iterable by treating them as already resolved Promises.
Expected Behavior:
- When all input Promises resolve, the output Promise resolves with an array containing their resolved values.
- When any input Promise rejects, the output Promise rejects with the error from that Promise.
- The order of the resolved values in the output array must match the order of the Promises in the input iterable.
Edge Cases:
- An empty iterable as input.
- An iterable containing non-Promise values.
- An iterable containing a mix of resolved, rejected, and pending Promises.
Examples
Example 1:
Input: [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]
Output: A Promise that resolves to [1, 2, 3]
Explanation: All input Promises resolve successfully. The output Promise aggregates their resolved values in order.
Example 2:
Input: [Promise.resolve('success'), Promise.reject('error'), Promise.resolve('another')]
Output: A Promise that rejects with 'error'
Explanation: The second Promise rejects. Promise.all rejects immediately with the rejection reason of the first rejected Promise.
Example 3:
Input: []
Output: A Promise that resolves to []
Explanation: An empty iterable results in an immediate resolution with an empty array.
Example 4:
Input: [1, Promise.resolve(2), 3]
Output: A Promise that resolves to [1, 2, 3]
Explanation: Non-Promise values are treated as resolved Promises.
Constraints
- The input to
myPromiseAllwill be an iterable (most commonly an array) of values. - The function should be efficient and not block the event loop unnecessarily.
- Do not use the built-in
Promise.allfunction in your implementation.
Notes
- Remember that Promises are asynchronous. You'll need to manage the state of each individual Promise and coordinate their completion.
- Consider how you will track the number of resolved Promises and the order in which their values should be stored.
- Using
Promise.resolve()on a non-Promise value is a good way to normalize all entries in the iterable into Promises.