Как избежать ошибок при асинхронных вызовах?

«Как избежать ошибок при асинхронных вызовах?» — вопрос из категории Архитектура, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ключевой подход — использование промисов (Promises) и синтаксиса async/await для структурированной обработки асинхронного кода, что устраняет "ад колбэков" и повышает читаемость. Обязательно обрабатывайте все возможные ошибки.

Основные практики:

  1. Обработка ошибок с async/await: Всегда оборачивайте await в try/catch.
    async function fetchData() {
        try {
            const data = await someAsyncOperation();
            // Обработка успешного результата
            return process(data);
        } catch (error) {
            // Централизованная обработка ошибки: логирование, fallback-значение, проброс
            console.error('Fetch failed:', error);
            return getDefaultData(); // или throw error;
        }
    }
  2. Обработка ошибок с промисами: Не забывайте про .catch() в конце цепочки.
    someAsyncOperation()
        .then(processData)
        .then(saveResult)
        .catch(error => {
            console.error('Operation chain failed:', error);
        });
  3. Параллельное выполнение с контролем ошибок: Используйте Promise.allSettled() вместо Promise.all(), если нужно получить результаты всех операций, даже неудачных.
    const results = await Promise.allSettled([
        fetchUser(),
        fetchPosts(),
        fetchComments()
    ]);
    const successful = results.filter(r => r.status === 'fulfilled');
    const errors = results.filter(r => r.status === 'rejected');
  4. Глобальный обработчик: Настройте глобальный обработчик для непойманных ошибок в промисах (unhandledrejection).
    window.addEventListener('unhandledrejection', event => {
        console.warn('Unhandled promise rejection:', event.reason);
        event.preventDefault(); // Предотвращает вывод ошибки в консоль браузера
    });

    Главное правило: предполагайте, что любая асинхронная операция может завершиться ошибкой, и явно предусматривайте этот сценарий.