Implement Promise.all
Write promiseAll(iterable) that behaves like Promise.all, without calling it. It returns a promise that:
- resolves with an array of results in the same order as the input, no matter which item settles first
- treats non-promise values (and thenables) as already-resolved values
- resolves with
[]for an empty input - rejects as soon as any item rejects (fail fast), with that same reason
It should accept any iterable, such as an array, a Set or a generator.
promiseAll([1, Promise.resolve(2), 3])→ resolves to[1, 2, 3]promiseAll([slow, fast])→ resolves to[slowResult, fastResult], even thoughfastsettles firstpromiseAll([])→ resolves to[]promiseAll([neverSettles, Promise.reject(err)])→ rejects witherrright away
Define promiseAll in the editor. 8 tests will call it.
Hint 1Return new Promise((resolve, reject) => { ... }) and turn the input into an array with Array.from, so you know how many items to wait for.
Hint 2Wrap every item in Promise.resolve(item) so plain values and thenables work, then store each result at its own index rather than pushing.
Hint 3Count finished items and call resolve(results) when the count reaches the total. Pass reject straight in as the error handler to fail fast, and resolve immediately for an empty input.
one clean solution
function promiseAll(iterable) {
return new Promise((resolve, reject) => {
const items = Array.from(iterable);
const results = new Array(items.length);
let remaining = items.length;
if (remaining === 0) {
resolve(results);
return;
}
items.forEach((item, index) => {
Promise.resolve(item).then((value) => {
results[index] = value;
remaining -= 1;
if (remaining === 0) resolve(results);
}, reject);
});
});
}