Обработка промисов и API fetch, управление ошибками | Вопросы для собеседования | Skilio
Обработка промисов и API fetch, управление ошибками
Вопрос:

Объясните, как вы бы написали функцию на TypeScript, которая использует fetch для выполнения вызова API и возвращает промис (Promise).

Подсказки:

  • Подумайте, как вы бы могли обработать обобщённый тип данных, возвращаемых API.
  • Подумайте, как бы вы управляли ошибками в функции async/await.
  • Возможно ли использование типа Awaited, чтобы вывести разрешённый тип промиса?

Превосходя ожидания:

  • Как создать пользовательский класс ошибок для более точной обработки ошибок при вызовах API.
  • Использование Promise.all для эффективной обработки нескольких асинхронных операций.
  • Как типы-утилиты TypeScript, такие как ReturnType, могут использоваться для вывода типов возвращаемых значений функций.
Ответ:

Для написания функции в TypeScript, которая использует fetch для выполнения API-запросов и возвращает промис, следуйте этим шагам:

  1. Определение типа ответа: Начните с определения типа данных, которые ожидается вернуть API. Используйте интерфейс или алиас типа для явного определения структуры ответа API. Например:

    interface ApiResponse {
      id: number;
      name: string;
      email: string;
    }
    
  2. Типизация функции fetch: Создайте функцию, которая использует fetch для выполнения API-запроса. Используйте обобщения (generics), чтобы обеспечить гибкость в типе ответа. Функция должна возвращать промис ожидаемого типа ответа.

    function fetchData<T>(url: string): Promise<T> {
      return fetch(url)
        .then(response => {
          if (!response.ok) {
            throw new Error('Сеть вернула некорректный ответ');
          }
          return response.json();
        });
    }
    
  3. Async/Await с обработкой ошибок: Используйте синтаксис async/await для более чистого и читабельного асинхронного кода. Реализуйте обработку ошибок с помощью блоков try/catch для управления исключениями.

    async function getData<T>(url: string): Promise<T> {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error('Ошибка получения данных');
        }
        const data: T = await response.json();
        return data;
      } catch (error) {
        console.error('Ошибка получения данных:', error);
        throw error;
      }
    }
    
  4. Использование типа Awaited: Используйте тип Awaited, чтобы вывести тип результирующего значения промиса. Это особенно полезно в сложных цепочках промисов или при использовании Promise.all.

    type ApiResponseType = Awaited<ReturnType<typeof getData<ApiResponse>>>;
    
  5. Пользовательский класс ошибок: Создайте пользовательский класс ошибок, чтобы обеспечить более точную обработку ошибок и контекст об ошибках при выполнении API-запросов. Это помогает различать различные типы ошибок.

    class ApiError extends Error {
      constructor(public statusCode: number, message: string) {
        super(message);
        this.name = 'ApiError';
      }
    }
    
    async function getDataWithCustomError<T>(url: string): Promise<T> {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new ApiError(response.status, 'Ошибка получения данных');
        }
        const data: T = await response.json();
        return data;
      } catch (error) {
        if (error instanceof ApiError) {
          console.error('Ошибка API:', error.statusCode, error.message);
        } else {
          console.error('Непредвиденная ошибка:', error);
        }
        throw error;
      }
    }
    
  6. Обработка нескольких промисов с Promise.all: При работе с несколькими асинхронными операциями используйте Promise.all, чтобы выполнить их одновременно. Определите результат с помощью массива ожидаемых типов ответа.

    async function fetchMultipleData<T>(urls: string[]): Promise<T[]> {
      try {
        const responses = await Promise.all(urls.map(url => fetch(url)));
        const data = await Promise.all(responses.map(response => response.json()));
        return data;
      } catch (error) {
        console.error('Ошибка получения данных:', error);
        throw error;
      }
    }
    
  7. Утилитарные типы для вывода типов возвращаемых значений: Используйте утилитные типы TypeScript, такие как ReturnType, чтобы вывести тип возвращаемого значения функций. Это обеспечивает согласованность и уменьшает избыточность в объявлениях типов.

    type FetchDataReturnType = ReturnType<typeof getData<ApiResponse>>;
    

Следуя этим рекомендациям, вы обеспечиваете надежность, поддерживаемость и типо-безопасность кода при взаимодействии с удаленным API.

0
TypeScript Новичок Опубликовано
© Skilio, 2025
Условия использования
Политика конфиденциальности
Мы используем файлы cookie, для персонализации сервисов и повышения удобства пользования сайтом. Если вы не согласны на их использование, поменяйте настройки браузера.