Перейти к основному содержимому
Модуль 7 · Урок 4 из 428/32 в курсе~12 min
Уроки модуля (4/4)

Ошибки в асинхронном коде

Асинхронные операции завершаются сбоем иначе, чем синхронные: ошибка приходит не сразу, оно приходит «позже», когда Promise переходит в состояние rejected. Давайте рассмотрим два основных инструмента.

try/catch с await

Когда вы помещаете await перед невыполненным обещанием, ошибка повторно выдается как обычное исключение: вы ловите его с помощью try/catch.

JS
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 по обещанию

В цепном стиле:

JS
fetch('/api/cose')
  .then((r) => r.json())
  .then((data) => console.log(data))
  .catch((err) => console.error(err));

.catch перехватывает любую ошибку, возникшую в предыдущей цепочке.

Promise.all терпит неудачу при первом отклонении

JS
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:

JS
const outcomes = await Promise.allSettled(ps);
// [{ status: 'fulfilled', value: 1 },
//  { status: 'rejected', reason: Error('no') },
//  { status: 'fulfilled', value: 3 }]

Попробуйте это

Упражнение#js.m7.l4.e1
Попыток: 0Загрузка…

Определите `readOrFallback(p, Fallback)` async: попытайтесь дождаться обещания p; если он отклонен, верните резервный вариант.

Загрузка редактора…
Показать подсказку

попробуйте {возврат ждут р; } catch {вернуть резервный вариант; }

Решение доступно после 3 попыток

Обзор упражнения

Упражнение#js.m7.l4.e2
Попыток: 0Загрузка…

Определите `allOrNothing(promises)` асинхронно: используйте Promise.all. Если хотя бы один не удался, верните пустой массив []. В противном случае верните значения.

Загрузка редактора…
Показать подсказку

попробуйте { return await Promise.all(обещания); } поймать {вернуться []; }

Решение доступно после 3 попыток