Какие знаешь методы работы с Promise
Разбор вопроса «Какие знаешь методы работы с Promise» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Вопрос
Какие знаешь методы работы с Promise
Профессия
Frontend Developer
Что хочет услышать интервьюер
Интервьюер хочет убедиться, что кандидат понимает основные методы работы с промисами, включая их комбинации (all, race и т. д.), а также умеет обрабатывать результаты и ошибки через then/catch/finally. Важно показать знание современных методов (например, allSettled и any).
Ключевые тезисы
- Promise.all() — принимает массив промисов и возвращает новый промис, который выполнится, когда все промисы в массиве завершатся, или отклоняется, если хотя бы один промис отклонён.
- Promise.allSettled() — аналогичен Promise.all(), но ждёт завершения всех промисов, независимо от их статуса (fulfilled/rejected), и возвращает массив результатов.
- Promise.race() — возвращает промис, который выполнится или отклонится первым из переданных промисов, с его результатом или ошибкой.
- Promise.any() — возвращает первый успешно выполнившийся промис из переданных, или отклоняется, если все промисы отклонены.
- Promise.resolve() и Promise.reject() — создают промисы, которые сразу выполняются (resolve) или отклоняются (reject) с указанным значением.
- Цепочки промисов (then/catch/finally) — методы для обработки результатов выполнения или ошибок, а также выполнения кода после завершения промиса.
Подробный ответ
Promise (Обещание) — это объект, представляющий результат успешного или неудачного завершения асинхронной операции. В JavaScript и TypeScript существует несколько методов для работы с промисами, которые позволяют эффективно управлять асинхронным кодом. Основные методы включают: Promise.all(), Promise.allSettled(), Promise.race(), Promise.any(), а также методы для создания промисов (Promise.resolve(), Promise.reject()) и обработки их результатов (then/catch/finally).
Promise.all() используется, когда нужно дождаться выполнения всех переданных промисов. Если хотя бы один промис отклонён, весь Promise.all() также отклоняется. Promise.allSettled(), в отличие от Promise.all(), ждёт завершения всех промисов, независимо от их статуса, и возвращает массив результатов с информацией о каждом промисе. Это полезно, когда важно обработать все результаты, даже если некоторые операции завершились с ошибкой.
Promise.race() возвращает первый завершившийся промис (независимо от его статуса), что полезно для реализации таймаутов или приоритизации запросов. Promise.any() похож на Promise.race(), но возвращает первый успешно выполнившийся промис, а если все промисы отклонены, то возвращает AggregateError. Эти методы помогают управлять асинхронными операциями более гибко.
Практические примеры
Пример 1
Пример использования Promise.all() для параллельного выполнения нескольких запросов:
const fetchUser = fetch('/api/user');
const fetchPosts = fetch('/api/posts');
Promise.all([fetchUser, fetchPosts])
.then(([userResponse, postsResponse]) => {
return Promise.all([userResponse.json(), postsResponse.json()]);
})
.then(([user, posts]) => {
console.log('User:', user);
console.log('Posts:', posts);
})
.catch(error => {
console.error('Ошибка в одном из запросов:', error);
});Пример 2
Пример использования Promise.race() для реализации таймаута:
const fetchData = fetch('/api/data');
const timeout = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Timeout')), 5000);
});
Promise.race([fetchData, timeout])
.then(response => response.json())
.then(data => console.log('Данные:', data))
.catch(error => console.error('Ошибка:', error));Пример 3
Пример использования Promise.allSettled() для обработки всех результатов, включая ошибки:
const promises = [
Promise.resolve('Успех'),
Promise.reject('Ошибка'),
Promise.resolve('Ещё один успех')
];
Promise.allSettled(promises)
.then(results => {
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('Успех:', result.value);
} else {
console.log('Ошибка:', result.reason);
}
});
});Частые ошибки
- Игнорирование обработки ошибок в цепочке промисов. Например, отсутствие блока catch() может привести к необработанным ошибкам.
- Использование Promise.all() без учёта того, что он отклоняется при первой ошибке. Если нужно обработать все результаты, лучше использовать Promise.allSettled().
- Путаница между Promise.race() и Promise.any(). Первый возвращает первый завершившийся промис (любого статуса), а второй — первый успешный.
Связанные темы
- Async/Await — современный синтаксис для работы с асинхронным кодом, который делает его более читаемым.
- Event Loop — механизм, который управляет выполнением асинхронного кода в JavaScript.
- Обработка ошибок в асинхронном коде — важно понимать, как правильно обрабатывать ошибки в цепочках промисов и async/await функциях.
Follow-up вопросы
В чем разница между Promise.all() и Promise.allSettled()?
Уровень: basic
Promise.all() завершается с ошибкой, если хотя бы один промис отклонён, а Promise.allSettled() ждёт завершения всех промисов и возвращает их статусы (fulfilled/rejected) и результаты/ошибки.
Как обработать ошибки в цепочке промисов?
Уровень: intermediate
Ошибки обрабатываются с помощью метода .catch(), который перехватывает любые ошибки в цепочке. Также можно использовать второй аргумент в .then() для обработки ошибок на конкретном этапе.
Когда стоит использовать Promise.race()?
Уровень: intermediate
Promise.race() полезен, когда нужно реагировать на первый завершившийся промис, например, для реализации таймаутов или приоритизации запросов.
Как Promise.any() отличается от Promise.race()?
Уровень: advanced
Promise.any() возвращает первый успешный промис, игнорируя отклонённые, пока хотя бы один не выполнится. Promise.race() возвращает первый завершившийся промис, независимо от его статуса.
Можно ли отменить промис? Как это сделать?
Уровень: advanced
Стандартные промисы нельзя отменить, но можно использовать AbortController с fetch или реализовать кастомное решение с флагом отмены, который проверяется в then/catch.
Какие знаешь макрозадачи
Разбор вопроса «Какие знаешь макрозадачи» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Какие знаешь способы работы с асинхронным кодом в JavaScript
Разбор вопроса «Какие знаешь способы работы с асинхронным кодом в JavaScript» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.