Skip to content
Async · Core · about 15 minutes

Promise.allSettled by hand

Implement promiseAllSettled(values) without the Promise combinators (the tests make them throw). It never rejects. When every item has settled it resolves with an array in input order of { status: 'fulfilled', value } or { status: 'rejected', reason }. In the tests a task [30, a] resolves with a after 30 ms and [30, boom, true] rejects with Error(boom); an outcome is [status, value, time]. The answer shows a reason as its message.

Start from

function promiseAllSettled(values) {
  // Resolve with one { status, value or reason } per item.
}

Hints

Each hint gives away a little more. Open one only when you need it.

  1. Hint 1

    It is promiseAll where a failure is also a result.

  2. Hint 2

    Give then two callbacks that both store an object at the item's index, then count down in a second then.

Solution

From here on the page gives the method away. If you are still solving, go back to the hints.

JavaScript
function promiseAllSettled(values) {
  return new Promise((resolve) => {
    const results = [];
    let left = values.length;
    if (left === 0) return resolve(results);
    values.forEach((value, index) => {
      Promise.resolve(value)
        .then(
          (result) => (results[index] = { status: "fulfilled", value: result }),
          (reason) => (results[index] = { status: "rejected", reason }),
        )
        .then(() => {
          if (--left === 0) resolve(results);
        });
    });
  });
}

What an interviewer looks for

The follow-up to Promise.all: use it when one failed request must not hide the others, for example a dashboard with independent widgets.