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

Помилки в асинхронному коді

Невдача асинхронних операцій відрізняється від синхронних: помилка виникає не відразу, воно надходить «пізніше», коли Promise переходить у стан відхилено. Давайте розглянемо два основних інструменти.

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'
}

Інші Promises продовжують працювати у фоновому режимі, але 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: спробуйте дочекатися Promise p; якщо його відхилено, поверніть запасний варіант.

Завантаження редактора…
Показати підказку

try { return очікувати p; } catch { return резервний варіант; }

Рішення доступне після 3 спроб

Повторна вправа

вправи#js.m7.l4.e2
Спроби: 0Завантаження…

Визначте `allOrNothing(promises)` async: використовуйте Promise.all. Якщо принаймні одна помилка, поверніть порожній масив []. В іншому випадку поверніть значення.

Завантаження редактора…
Показати підказку

try { return await Promise.all(promises); } catch { return []; }

Рішення доступне після 3 спроб