Door 18 | JS Adventskalender
Skip to content

Door 18

Published: at 07:00 AMSuggest Changes

Promise.allSettled – Keeping All Promises in View

In modern JavaScript applications, it is common practice to execute multiple asynchronous operations simultaneously – such as loading data from different APIs, uploading multiple files, or retrieving different configuration values. Often you want to wait until all these operations are completed to then make a decision or update a display status in the UI. This is where Promise.allSettled() comes into play.

What is Promise.allSettled()?

Promise.allSettled() was introduced with ES2020 and gives you a convenient way to keep track of the outcome of multiple Promises simultaneously. Unlike Promise.all(), which aborts at the first error, Promise.allSettled() always delivers a result when all passed Promises have either been fulfilled or rejected.

The return value of Promise.allSettled() is a Promise that is fulfilled as soon as all Promises have been processed. The result is an array of objects, where each object has two properties:

A classic example:

const promise1 = Promise.resolve('Data from Server A');
const promise2 = Promise.resolve('Data from Server B');
const promise3 = Promise.reject('Error fetching from Server C');

Promise.allSettled([promise1, promise2, promise3])
  .then(results => {
    console.log(results);
    // [
    //   { status: 'fulfilled', value: 'Data from Server A' },
    //   { status: 'fulfilled', value: 'Data from Server B' },
    //   { status: 'rejected', reason: 'Error fetching from Server C' }
    // ]

    // You can see: Even if one operation fails, you still get
    // the results of all other Promises. This allows you to specifically react to partial errors.
  });

Difference from Promise.all()

Comparison:

// With Promise.all()
Promise.all([promise1, promise2, promise3])
  .then(results => {
    // Only reached if ALL Promises were fulfilled
    console.log('All succeeded:', results);
  })
  .catch(error => {
    // Immediately entered on the first error
    console.error('At least one failed:', error);
  });

// With Promise.allSettled()
Promise.allSettled([promise1, promise2, promise3])
  .then(results => {
    // ALWAYS reached when all Promises are completed
    const successful = results.filter(r => r.status === 'fulfilled');
    const failed = results.filter(r => r.status === 'rejected');
    
    console.log(`${successful.length} successful, ${failed.length} failed`);
  });

Practical Use Cases

1. Multiple API Calls:

async function fetchAllData() {
  const endpoints = [
    '/api/users',
    '/api/posts',
    '/api/comments'
  ];

  const promises = endpoints.map(url => fetch(url).then(r => r.json()));
  const results = await Promise.allSettled(promises);

  results.forEach((result, index) => {
    if (result.status === 'fulfilled') {
      console.log(`${endpoints[index]}: Success`, result.value);
    } else {
      console.error(`${endpoints[index]}: Failed`, result.reason);
    }
  });
}

2. File Upload:

async function uploadFiles(files) {
  const uploadPromises = files.map(file => uploadFile(file));
  const results = await Promise.allSettled(uploadPromises);

  const successful = results.filter(r => r.status === 'fulfilled').length;
  const failed = results.filter(r => r.status === 'rejected').length;

  return {
    message: `${successful} of ${files.length} files uploaded successfully`,
    failed: failed,
    details: results
  };
}

3. Validation of Multiple Inputs:

async function validateForm(formData) {
  const validations = [
    validateEmail(formData.email),
    validatePhone(formData.phone),
    validateAddress(formData.address)
  ];

  const results = await Promise.allSettled(validations);

  const errors = results
    .filter(r => r.status === 'rejected')
    .map(r => r.reason);

  return {
    valid: errors.length === 0,
    errors: errors
  };
}

Conclusion

Promise.allSettled() is a valuable tool when you need to execute multiple asynchronous operations and want to know the outcome of each individual operation – regardless of whether they were successful or not. It enables robust error handling and gives you full control over the results of all Promises.

Use Promise.allSettled() in your next project and experience how it simplifies working with multiple asynchronous operations!


Previous Post
Door 19
Next Post
Door 17