How do you implement Promise.all from scratch?
Promise.all runs many promises in parallel and resolves to an array of results, or rejects on the first failure.
Return a new Promise and a results array.
As each promise resolves, store its value at the same index and count it.
Resolve when the count reaches the total.
Reject immediately if any promise rejects.
Remember: keep results in input order, and resolve right away for an empty input.
function promiseAll(promises) {
return new Promise((resolve, reject) => {
if (!promises.length) return resolve([]);
const results = new Array(promises.length);
let completed = 0;
promises.forEach((p, i) => {
Promise.resolve(p).then(value => {
results[i] = value; // Maintain order
completed++;
if (completed === promises.length) resolve(results);
}).catch(reject); // First rejection rejects all
});
});
}
// Test
promiseAll([
Promise.resolve(1),
new Promise(r => setTimeout(() => r(2), 100)),
Promise.resolve(3)
]).then(console.log); // [1, 2, 3] (in order)
promiseAll([Promise.resolve(1), Promise.reject('err')])
.catch(console.log); // 'err'Counter tracks completed promises. results[i] maintains order (not completion order). Promise.resolve wraps non-promises.
When all complete (completed === length), resolve with all results. First rejection immediately rejects the whole Promise.all.
Key details: maintain order (results[i], not push), handle non-promises (Promise.resolve wrapper), empty array edge case (resolve immediately), and fail-fast (first rejection). The counter approach (not checking every time) is optimal.