Q19: Implement a polyfill for Promise.all().

Difficulty:IntermediateTopic:Promises

Answer

Promise.all() accepts an iterable of promises or other values and returns a promise that fulfills when every input fulfills. Results preserve the original input order, regardless of completion order. It rejects when an input rejects.

if (!Promise.myAll) {
  Promise.myAll = function (iterable) {
    return new Promise((resolve, reject) => {
      let items;

      try {
        items = Array.from(iterable);
      } catch (error) {
        reject(error);
        return;
      }

      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--;

            if (remaining === 0) {
              resolve(results);
            }
          },
          reject
        );
      });
    });
  };
}

Promise.myAll([
  Promise.resolve(1),
  2,
  Promise.resolve(3)
]).then(console.log);
// [1, 2, 3]

Explanation

  1. Convert the iterable into an array.
  2. Create a results array with the same number of slots.
  3. Resolve each input using Promise.resolve().
  4. Store each fulfilled value at its original index.
  5. Resolve the outer promise when every input fulfills.
  6. Reject the outer promise if an input rejects.

Interview edge cases

  • An empty iterable produces a fulfilled promise containing an empty array.
  • Non-promise values are accepted.
  • Results preserve input order, not completion order.
  • Native Promise.all() has detailed iterable and constructor semantics that a production-quality polyfill must preserve.
Preserving result order
const first = new Promise(resolve => setTimeout(() => resolve("first"), 100));
const second = Promise.resolve("second");

Promise.myAll([first, second]).then(console.log);
// ["first", "second"]
💡 The second promise can fulfill first, but Promise.all returns values in input order.
Key Takeaways
  • Promise.all fulfills only when every input fulfills and rejects when an input rejects.
  • Result ordering follows input order, not completion order.