Goal: Understand the inner workings of
Promise.all()and practice creating and managing promises.
promiseAll function should return a new Promise.promises array.results array to store the results of the resolved promises and a completed counter to track the number of finished ones.promises array:
Promise.resolve() to handle both promises and regular values..then(), add the result to the results array, maintaining the original order. Increment the completed counter.completed equals the length of the promises array, it means all promises are resolved. Call resolve() with the results array..catch(), immediately call reject() with the error.const promiseAll = (promises) => {
// Return a new promise that will manage the asynchronous operation.
return new Promise((resolve, reject) => {
// An array to store the results of the resolved promises.
const results = [];
// A counter to track the number of resolved promises.
let completed = 0;
// The total number of promises in the array for convenience.
const promisesCount = promises.length;
// If the input array is empty, immediately resolve the promise with an empty array.
// This matches the behavior of the native Promise.all().
if (promisesCount === 0) {
resolve([]);
return;
}
// Iterate over each item in the input array.
promises.forEach((promise, index) => {
// Wrap each item in Promise.resolve().
// This allows handling both actual promises and regular values (e.g., numbers, strings),
// which will be treated as already resolved promises.
Promise.resolve(promise)
.then(value => {
// When a promise resolves successfully, save its result.
// The result is placed in the `results` array at the same index
// as the original promise to maintain the order.
results[index] = value;
// Increment the counter of resolved promises.
completed++;
// Check if all promises have completed.
// If the number of completed promises equals the total number,
// it means all tasks have finished successfully.
if (completed === promisesCount) {
// Resolve the main promise, returning the array of results.
resolve(results);
}
})
// If any of the promises in the chain rejects,
// we immediately reject the main promise.
// The entire Promise.all() operation fails,
// and the rejection reason of the first failed promise is returned.
.catch(reject);
});
});
};Solution Analysis:
You need to implement your own version of the built-in Promise.all() static method.
The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved. It rejects with the reason of the first promise that rejects.
All promises resolve:
const p1 = Promise.resolve(3);
const p2 = 1337;
const p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
promiseAll([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});One of the promises rejects:
const p1 = Promise.resolve(1);
const p2 = Promise.reject('error');
const p3 = Promise.resolve(3);
promiseAll([p1, p2, p3]).catch(error => {
console.error(error); // "error"
});promiseAll.Promise.Goal: Understand the inner workings of
Promise.all()and practice creating and managing promises.
promiseAll function should return a new Promise.promises array.results array to store the results of the resolved promises and a completed counter to track the number of finished ones.promises array:
Promise.resolve() to handle both promises and regular values..then(), add the result to the results array, maintaining the original order. Increment the completed counter.completed equals the length of the promises array, it means all promises are resolved. Call resolve() with the results array..catch(), immediately call reject() with the error.const promiseAll = (promises) => {
// Return a new promise that will manage the asynchronous operation.
return new Promise((resolve, reject) => {
// An array to store the results of the resolved promises.
const results = [];
// A counter to track the number of resolved promises.
let completed = 0;
// The total number of promises in the array for convenience.
const promisesCount = promises.length;
// If the input array is empty, immediately resolve the promise with an empty array.
// This matches the behavior of the native Promise.all().
if (promisesCount === 0) {
resolve([]);
return;
}
// Iterate over each item in the input array.
promises.forEach((promise, index) => {
// Wrap each item in Promise.resolve().
// This allows handling both actual promises and regular values (e.g., numbers, strings),
// which will be treated as already resolved promises.
Promise.resolve(promise)
.then(value => {
// When a promise resolves successfully, save its result.
// The result is placed in the `results` array at the same index
// as the original promise to maintain the order.
results[index] = value;
// Increment the counter of resolved promises.
completed++;
// Check if all promises have completed.
// If the number of completed promises equals the total number,
// it means all tasks have finished successfully.
if (completed === promisesCount) {
// Resolve the main promise, returning the array of results.
resolve(results);
}
})
// If any of the promises in the chain rejects,
// we immediately reject the main promise.
// The entire Promise.all() operation fails,
// and the rejection reason of the first failed promise is returned.
.catch(reject);
});
});
};Solution Analysis:
You need to implement your own version of the built-in Promise.all() static method.
The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved. It rejects with the reason of the first promise that rejects.
All promises resolve:
const p1 = Promise.resolve(3);
const p2 = 1337;
const p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
promiseAll([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});One of the promises rejects:
const p1 = Promise.resolve(1);
const p2 = Promise.reject('error');
const p3 = Promise.resolve(3);
promiseAll([p1, p2, p3]).catch(error => {
console.error(error); // "error"
});promiseAll.Promise.The code editor is intentionally hidden on mobile.
Believe me, it's for the best: I am protecting you from the temptation to code in less-than-ideal conditions. A small screen and a virtual keyboard are not the best tools for a programmer.
📖 Now: Study the task, think through the solution. Act like a strategist.
💻 Later: Sit down at your computer, open the site, and implement all your ideas comfortably. Act like a code-jedi!