Hiprup

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.

  1. Return a new Promise and a results array.

  2. As each promise resolves, store its value at the same index and count it.

  3. Resolve when the count reaches the total.

  4. 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.

How do you implement Promise.all from scratch? | Hiprup