Promise.allSettled in babel ES6 implementation

const allSettled = promises =>
  Promise.all(promises.map(promise => promise
    .then(value => ({ state: 'fulfilled', value }))
    .catch(reason => ({ state: 'rejected', reason }))
  ));

Or if you insist on polyfilling it:

if (Promise && !Promise.allSettled) {
  Promise.allSettled = function (promises) {
    return Promise.all(promises.map(function (promise) {
      return promise.then(function (value) {
        return { state: 'fulfilled', value: value };
      }).catch(function (reason) {
        return { state: 'rejected', reason: reason };
      });
    }));
  };
}

Taken from here


2019 Answer

There was a proposal to add this function to the ECMAScript standard, and it has been accepted! Check out the Promise.allSettled docs for details.

Original Answer

If you take a look at the implementation of q.allSettled you'll see it's actually quite simple to implement. Here's how you might implement it using ES6 Promises:

function allSettled(promises) {
    let wrappedPromises = promises.map(p => Promise.resolve(p)
        .then(
            val => ({ status: 'fulfilled', value: val }),
            err => ({ status: 'rejected', reason: err })));
    return Promise.all(wrappedPromises);
}

Alternatively, which is a good algorithm for me to try to implement?

  1. create a new promise with an executor function
  2. use a counter/result array in the scope of the executor
  3. register a then() callback with each parent promise saving the results in the array
  4. resolve/reject promise from step 1 when counter indicates that all parent promises are done

2020 answer:

What the other answers are trying to do is to implement Promise.allSettled themselves. This was already done by the core-js project.

What you need to do is to make babel polyfill Promise.allSettled for you via core-js. The way you configure it to do so is through @babel/preset-env like so:

presets: [
    ['@babel/preset-env', {
        useBuiltIns: 'usage',
        corejs: {version: 3, proposals: true},
    }],
],

In your build artifact this will add a call to require("core-js/modules/esnext.promise.all-settled") which monkeypatches the .allSettled function to the promises API.