Зависит от того, как и где вы хотите обработать сбой.
Один из подходов к « массиву асинхронных задач, выполнение которого может завершиться с ошибкой », выглядит следующим образом:
async function myAsyncFunction(argument) {
const success = async res => ({ success: await res }) // Promise<{success: res}>
const error = async err => ({ error: await err }) // Promise<{error: e}>
const arrayTasks = [
{
run: async () => getDataAsync()
}
},
{
run: async () => getDataAsync()
}
]
const runWithResult = task => task.run().then(success).catch(error)
const outcomes = await Promise.all(arrayTasks.map(runWithResult))
console.log(outcomes) // array of {error: e} | {success: res}
}
Вы можете связать обработчик .catch()
в async
функция, и она имеет тот же эффект, что и ее упаковка в try
/ catch
.
Подробнее здесь , если вы заинтересованы. В разделе «Refactor без fp-ts» показано, как уменьшить этот массив с [{error: e} | {success: res}]
до {error: [], success: []}
, с которым проще работать:
const { error, success } = outcomes.reduce((acc, o) => o.error ?
{ error: [...acc.error, o.error], success: acc.success } :
{ error: acc.error, success: [...acc.success, o.success] },
{ error: [], success: [] })
Это тип FP, называемый Either
- операция может вернуть «или» (в данном случае) значение или ошибку.
Ваш код не генерирует этот подход.
Если вы знаете, что что-то может не получиться, это не исключение. Исключения составляют случаи, когда происходит непредвиденный сбой, ИМХО.
«Задачам, которые могут выйти из строя», которые известны заранее, просто нужно написать код пути ошибки.
Если вы выберете такой подход, я рекомендую построить его как первоклассную государственную редукционную машину, например:
// Takes an array of async tasks that may throw of shape {run: () => Promise<result>}
// Returns Promise<{error: error[], success: result[]}>
async function executeAsyncTasks(arrayOfAsyncTasks) {
const success = async res => ({ success: await res }) // Promise<{success: res}>
const error = async err => ({ error: await err }) // Promise<{error: e}>
const runWithResult = task => task.run().then(success).catch(error)
const outcomes = await Promise.all(arrayOfAsyncTasks.map(runWithResult))
const outcomesFlat = outcomes.reduce((acc, o) => o.error ?
{ error: [...acc.error, o.error], success: acc.success } :
{ error: acc.error, success: [...acc.success, o.success] },
{ error: [], success: [] })
return outcomesFlat
}