Вопрос проверяет понимание различий между синтаксисом async/await с try/catch и цепочками промисов для обработки ошибок в асинхронном коде.
В современном JavaScript существует два основных способа работы с асинхронными операциями: цепочки промисов (.then/.catch) и синтаксис async/await с try/catch. Оба подхода функционально эквивалентны, но различаются по читаемости и удобству поддержки кода.
async/await позволяет писать асинхронный код, который выглядит как синхронный. Это особенно важно при последовательных асинхронных операциях, где результат одного запроса нужен для следующего. Цепочки .then в таких случаях создают вложенность, которая усложняет понимание потока выполнения.
// Цепочка промисов
fetchUser(id)
.then(user => fetchPosts(user.id))
.then(posts => fetchComments(posts[0].id))
.catch(err => console.error(err));
// async/await с try/catch
async function getData(id) {
try {
const user = await fetchUser(id);
const posts = await fetchPosts(user.id);
const comments = await fetchComments(posts[0].id);
return comments;
} catch (err) {
console.error(err);
}
}try/catch обрабатывает как асинхронные ошибки (от rejected промисов), так и синхронные исключения, возникшие до первого await. В цепочке .then/.catch синхронные ошибки нужно обрабатывать отдельно, иначе они могут остаться незамеченными.
// try/catch ловит всё
async function example() {
try {
const data = JSON.parse(malformedJSON); // синхронная ошибка
const result = await fetchData(data); // асинхронная ошибка
} catch (err) {
// обрабатываем оба типа ошибок
}
}
// В цепочке .catch не поймает синхронную ошибку
function example() {
const data = JSON.parse(malformedJSON); // упадёт здесь
return fetchData(data).catch(err => { /* только асинхронные */ });
}При использовании async/await можно легко применять обычные конструкции управления потоком: if, for, while. В цепочках промисов это требует создания дополнительных функций или использования сложных конструкций.
// async/await с циклом
async function processItems(items) {
for (const item of items) {
try {
await processItem(item);
} catch (err) {
console.error(`Failed on ${item}:`, err);
}
}
}
// Цепочка промисов с циклом - менее читаемо
function processItems(items) {
return items.reduce((promise, item) => {
return promise
.then(() => processItem(item))
.catch(err => console.error(`Failed on ${item}:`, err));
}, Promise.resolve());
}Используйте try/catch с async/await в большинстве случаев для нового кода, особенно когда требуется последовательная обработка, условная логика или обработка нескольких типов ошибок. Цепочки .then/.catch могут быть оправданы при параллельных операциях (Promise.all) или в очень простых сценариях с одним асинхронным вызовом.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию