Уроки модуля (4/4)
Ошибки в асинхронном коде
Асинхронные операции завершаются сбоем иначе, чем синхронные: ошибка приходит не сразу, оно приходит «позже», когда Promise переходит в состояние rejected. Давайте рассмотрим два основных инструмента.
try/catch с await
Когда вы помещаете await перед невыполненным обещанием, ошибка повторно выдается как
обычное исключение: вы ловите его с помощью try/catch.
async function safeRead() {
try {
const r = await fetch('/api/cose');
if (!r.ok) throw new Error('HTTP ' + r.status);
return await r.json();
} catch (err) {
console.error('network error:', err.message);
return null;
}
}Это наиболее читаемый шаблон: вы пишете «счастливый путь» линейно и обрабатываете все в одном блоке.
.catch по обещанию
В цепном стиле:
fetch('/api/cose')
.then((r) => r.json())
.then((data) => console.log(data))
.catch((err) => console.error(err));.catch перехватывает любую ошибку, возникшую в предыдущей цепочке.
Promise.all терпит неудачу при первом отклонении
const ps = [Promise.resolve(1), Promise.reject(new Error('no')), Promise.resolve(3)];
try {
const r = await Promise.all(ps);
} catch (err) {
console.log(err.message); // 'no'
}Остальные промисы продолжают работать в фоновом режиме, но Promise.all «устанавливается» при первой ошибке.
Если вам нужны результаты всех из них (включая сбои), используйте Promise.allSettled:
const outcomes = await Promise.allSettled(ps);
// [{ status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: Error('no') },
// { status: 'fulfilled', value: 3 }]Попробуйте это
Определите `readOrFallback(p, Fallback)` async: попытайтесь дождаться обещания p; если он отклонен, верните резервный вариант.
Показать подсказку
попробуйте {возврат ждут р; } catch {вернуть резервный вариант; }
Решение доступно после 3 попыток
Обзор упражнения
Определите `allOrNothing(promises)` асинхронно: используйте Promise.all. Если хотя бы один не удался, верните пустой массив []. В противном случае верните значения.
Показать подсказку
попробуйте { return await Promise.all(обещания); } поймать {вернуться []; }
Решение доступно после 3 попыток