Отловить ошибки в Promise.all

Безопасная альтернатива Javascript Promise.all

Ожидание всех обещаний, включая ошибки

Если вы разработчик Javascript, вы, скорее всего, использовали стандартный встроенный объект Promise и его API Promise.all, который ожидает, пока все обещания, предоставленные в массиве, не будут разрешены. Это очень элегантный способ дождаться различных асинхронных результатов, прежде чем продолжить бизнес-логику.

Но этот API не обрабатывает ошибки. Каждый раз, когда в массиве обещаний возникает хотя бы одна ошибка, функция немедленно останавливается и никаких дальнейших результатов не ожидается.

Promise.allSettled ожидает всех асинхронных результатов

К счастью, есть второй API под названием Promise.allSettled, который гарантирует выполнение всех обещаний, независимо от того, является ли результат действительным или ошибочным. Следующий код демонстрирует его использование, которое действительно просто, но может сэкономить вам много головной боли.

Основное отличие от Promise.all заключается в том, что каждое обещание преобразуется в кортеж информации, где доступны как состояние (выполнено или отклонено), так и значение (в случае выполнения) или причина (в случае отклонения). .

Предоставление пустого массива

Особый случай, о котором вы должны знать, заключается в том, что когда Promise.allSettled получает в качестве входных данных пустой массив, он немедленно возвращается к пустому массиву. Это звучит логично и является ожидаемым поведением, но я все же хотел указать на это.

/**
 * A simple dummy function that
 * fetches data from multiple
 * endpoints related to a user.
 */
async function fetchUserData(id){
  // A simple array of promises.
  // The first two parameters are
  // mock calls from down below.
  const promises = [
    fetchUserHistory(id),
    fetchUserProfile(id),
    // For testing only, let's throw.
    Promise.reject(new Error('an error'))
];
  
  const values = await Promise.allSettled(promises);
  // values === [
  //    { status: "fulfilled", value: [1, 2, 3] },
  //    { status: "fulfilled", value: {name:"dummy"} },
  //    { status: "rejected", reason: {}
  // ]
}

// The following functions are just mocks
// and should help improve readability
// of the example at the top.

async function fetchUserHistory(id){
  return Promise.resolve([1,2,3]);
}

async function fetchUserProfile(id){
  return Promise.resolve({ name: "dummy" });
}

Как видите, Promise.allSettled - очень хорошее дополнение к Promise.all, позволяющее ожидать всех результатов, независимо от их результатов. Я не думаю, что этот API подойдет для каждого случая использования, но он наверняка избавит вас от упаковки асинхронных вызовов во вспомогательный блок try-catch.