> Можно ли создать функцию для запроса продуктов, которая возвращает промис (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: ЛигаСтавок
Стек: JavaScript
> Пример ответа
Короткий ответ
Да, можно. Функция для запроса продуктов может возвращать промис - это стандартный паттерн в JavaScript. Промис представляет асинхронную операцию, которая завершится либо успешно с данными продуктов, либо с ошибкой. Такой подход позволяет использовать async/await, then/catch или Promise.all для параллельных запросов. Главное - правильно обработать ошибки сети, статусы ответа и валидацию данных.
Подробное объяснение
Функция, возвращающая промис, - это основа асинхронного программирования в JavaScript. Для запроса продуктов обычно используют fetch, который сам возвращает промис. Однако важно обернуть его в собственную функцию, чтобы:
- инкапсулировать логику запроса (URL, заголовки, параметры);
- добавить обработку ошибок (сетевые сбои, HTTP-статусы, парсинг JSON);
- обеспечить типизацию или валидацию данных;
- упростить тестирование и переиспользование.
Промис может быть создан тремя способами:
- Явно через
new Promise- когда нужно контролировать асинхронную логику вручную (например, таймауты, retry). - Через
asyncфункцию - она автоматически оборачивает возвращаемое значение в промис. - Через
fetchили другую библиотеку - они уже возвращают промис, но их нужно обернуть для добавления своей логики.
Для уровня senior важно показать понимание:
- race conditions - если пользователь быстро меняет фильтры, старые ответы могут перезаписать новые;
- отмены запросов - через
AbortController; - кэширования - чтобы не делать повторные запросы;
- обработки ошибок - не только
catch, но и проверкаresponse.ok, парсинг ошибок от сервера.
На практике
В реальном коде функция запроса продуктов обычно выглядит как модуль с конфигурацией. Она принимает параметры (фильтры, пагинацию, сортировку) и возвращает промис с нормализованными данными. Важно:
- использовать
async/awaitдля читаемости; - обрабатывать ошибки через
try/catchвнутри функции, а не только на месте вызова; - возвращать единый формат ошибки (например,
{ error: true, message }); - учитывать таймауты и возможность отмены.
Для senior-позиции стоит упомянуть, что промис - это не просто "обёртка над fetch", а инструмент для управления асинхронным потоком. Можно показать, как комбинировать несколько запросов через Promise.all или Promise.allSettled, как обрабатывать частичные ошибки.
Пример кода
JAVASCRIPT// Базовый вариант с async/awaitasync function fetchProducts(filters = {}) {const query = new URLSearchParams(filters).toString();const response = await fetch(`/api/products?${query}`, {headers: { 'Content-Type': 'application/json' },});if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.json();return data.products; // предполагаем, что сервер возвращает { products: [...] }}// Вариант с отменой и таймаутомfunction fetchProductsWithCancel(filters, signal) {const controller = new AbortController();const timeoutId = setTimeout(() => controller.abort(), 5000);const externalSignal = signal;if (externalSignal) {externalSignal.addEventListener('abort', () => controller.abort());}return fetch(`/api/products?${new URLSearchParams(filters)}`, {signal: controller.signal,}).then(response => {clearTimeout(timeoutId);if (!response.ok) throw new Error(`HTTP ${response.status}`);return response.json();}).then(data => data.products).catch(error => {if (error.name === 'AbortError') {throw new Error('Request was cancelled');}throw error;});}// Использованиеtry {const products = await fetchProducts({ category: 'electronics', page: 1 });console.log(products);} catch (error) {console.error('Failed to load products:', error);}
Как отвечать на собеседовании
Начните с прямого ответа "да", затем покажите минимальный пример с fetch. После этого углубитесь в детали:
- объясните, почему
asyncфункция автоматически возвращает промис; - покажите, как обрабатывать ошибки (сетевые, HTTP, парсинг);
- упомяните
AbortControllerдля отмены запросов; - обсудите кэширование и дебаунс для фильтров;
- если спросят про
new Promise- покажите, когда он нужен (например, для обёртки callback-функций).
Для senior важно продемонстрировать системное мышление: не просто "функция возвращает промис", а "как эта функция вписывается в архитектуру приложения". Расскажите про обработку гонок, мемоизацию, обработку ошибок на уровне UI.
Что проверяет интервьюер
Интервьюер оценивает:
- понимание асинхронности в JavaScript (event loop, microtasks);
- умение работать с
fetchи обрабатывать ошибки; - знание продвинутых паттернов:
AbortController,Promise.all,Promise.allSettled; - способность писать чистый, переиспользуемый код;
- умение объяснять trade-off между
async/awaitиthen/catch; - понимание проблем реального мира: race conditions, таймауты, повторные запросы.
Для senior также важно показать, что вы думаете о тестируемости (инъекция зависимостей, моки) и о производительности (кэширование, дебаунс).
Типичные ошибки
- Не проверять
response.ok- считать любой ответ успешным, даже 404 или 500. - Забывать про
try/catch- ошибка сети или парсинга упадёт необработанной. - Игнорировать отмену запросов - при быстрой смене фильтров старые ответы перезапишут новые.
- Возвращать весь
responseвместо данных - усложняет использование функции. - Смешивать
async/awaitи.then()без необходимости - код становится менее читаемым. - Не обрабатывать таймауты - запрос может висеть бесконечно.
- Создавать
new Promiseбез необходимости - если можно использоватьasyncилиfetch.
> Похожие задачи по frontend
Как получить ключ элемента в JavaScript
Как добавить новый метод в стандартный объект Array через prototype в JavaScript
Как реализовать таймаут с abort для запроса в JavaScript
Как реализовать функцию promisify в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью