promise.all()




Prompt
Implement a function called customPromiseAll
that takes an array of promises as input and returns a new promise that resolves with an array of resolved values from the input promises, or rejects with the reason of the first promise that was rejected.
The function should have the following signature:
/**
* Implement the `customPromiseAll` function
* @param {Array<Promise>} promises - An array of Promises
* @returns {Promise<Array>} - A new Promise that resolves with an array of resolved
* values from the input promises, or rejects with the
* reason of the first promise that was rejected.
*/
function customPromiseAll(promises) {
// Your implementation here
}
The customPromiseAll
function should behave similar to the native Promise.all
method in JavaScript, but you cannot use Promise.all
in your implementation.
Here are some examples to test your solution:
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
customPromiseAll([promise1, promise2, promise3]).then(
(values) => {
console.log(values); // Expected output: [3, 42, "foo"]
}
);
const promise1 = Promise.reject('Error 1');
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
customPromiseAll([promise1, promise2, promise3])
.then((values) => {
console.log(values); // This line should not be reached
})
.catch((error) => {
console.log(error); // Expected output: "Error 1"
});
customPromiseAll([]).then((values) => {
console.log(values); // Expected output: []
});
Your implementation should handle various cases, including an empty input array, a mix of resolved and rejected promises, and promises that resolve with non-Promise values.
Start by creating a new Promise that will be returned by
the customPromiseAll
function. This Promise will be
resolved or rejected based on the outcome of the input
promises. You'll need to create a Promise executor
function that handles the resolution or rejection of the
outer Promise.
Inside the Promise executor function, you need to iterate
over the input array of promises. You can use a for
loop
or the forEach
method to iterate over the array. For
each promise in the array, ensure that it is a Promise
object by calling Promise.resolve(promise)
. This will
handle both Promise and non-Promise values.
After ensuring that each value is a Promise object, you
need to handle its resolution or rejection. Chain a then
handler to handle the resolved value and a catch
handler
to handle the rejected promise. In the then
handler,
you'll need to store the resolved values in an array. In
the catch
handler, you'll need to reject the outer
Promise with the reason for rejection.
As you're handling each promise, keep track of the number of resolved promises. When the number of resolved promises is equal to the length of the input array, it means that all promises have been resolved. At this point, you can resolve the outer Promise with the array of resolved values. If any promise is rejected before all promises are resolved, the outer Promise should be rejected with the reason for rejection.
Solution
Explanation
- The function takes an array of promises as input.
- It initializes an empty array
results
to store the resolved values from the input promises. - It initializes a variable
completedPromisesCount
to keep track of the number of promises that have been resolved. - The function creates and returns a new Promise.
- Inside the Promise executor function, it iterates over the input
promises
array using theforEach
method. - For each promise in the array:
- It calls
Promise.resolve(promise)
to ensure that the value is a Promise object, even if it's a non-Promise value like a number or a string. - It chains a
then
handler to the resolved Promise, which:- Increments the
completedPromisesCount
counter. - Stores the resolved value in the
results
array at the corresponding index (results[index] = value
). - If all promises have been resolved (
completedPromisesCount === promises.length
), it resolves the outer Promise with theresults
array.
- Increments the
- It also chains a
catch
handler to handle any rejected promises, which rejects the outer Promise with the reason for rejection.
- It calls
- If the input promises array is empty, the outer Promise is immediately resolved with an empty array.
Key Aspects
- Handling non-Promise values: By calling
Promise.resolve(promise)
, the solution ensures that even non-Promise values are wrapped in a Promise object before being handled. - Collecting resolved values: The resolved values from each Promise are stored in the
results
array at the corresponding index (results[index] = value
). - Tracking completed promises: The
completedPromisesCount
counter is used to keep track of how many promises have been resolved. When all promises have been resolved (completedPromisesCount === promises.length
), the outer Promise is resolved with theresults
array. - Handling rejected promises: If any Promise is rejected, the
catch
handler rejects the outer Promise with the reason for rejection. This ensures that the first rejected promise causes the entirecustomPromiseAll
Promise to reject, following the behavior of the nativePromise.all
method. - Handling empty input array: If the input
promises
array is empty, the outer Promise is immediately resolved with an empty array, as per the expected behavior ofPromise.all
.