Search code examples
javascriptnode.jses6-promise

Alternative for Promise.allSettled


I am currently using Promise.allSettled to wait for all my promises to finish(irrespective of whether they resolve or get rejected).

Since my project is compliant to Node v12.3.1 I am unable to use this? What other simple alternatives can I use.

Sample code:

async function runner() {
    let promises = [];
    for(let i=0; i<10; i++) {
        promises.push(fetcher())
    }
    await Promise.allSettled(promises).then(([results]) => console.log(results.length));
    console.log('continue work...');
}

Note: Promise.allSettled is available from Node version >12.9.
Adding shims is also not an option.


Solution

  • There's a small polyfill trick that you can do manually to simulate the effects of Promise.allSettled.

    Here's the snippet.

    if (!Promise.allSettled) {
      Promise.allSettled = promises =>
        Promise.all(
          promises.map((promise, i) =>
            promise
              .then(value => ({
                status: "fulfilled",
                value,
              }))
              .catch(reason => ({
                status: "rejected",
                reason,
              }))
          )
        );
    }
    
    Promise.allSettled(promises).then(console.log);
    

    That means map all of the promises, then return the results, either successful or rejected.

    An alternative, if you do not want the object-like nature of Promise.all, the following snippet may help. This is very simple, you just need to add .catch method here.

    const promises = [
      fetch('/something'),
      fetch('/something'),
      fetch('/something'),
    ].map(p => p.catch(e => e)); // this will prevent the promise from breaking out, but there will be no 'result-object', unlike the first solution.
    
    await Promise.all(promises);