Промисы в JavaScript представляют собой объект, который используется для асинхронных операций и позволяет обрабатывать результат операции после её завершения. Промис может находиться в трёх состояниях:
Создание промиса осуществляется с помощью конструктора
Promise:
const promise = new Promise((resolve, reject) => {
// асинхронная операция
if (успех) {
resolve("Результат успешной операции");
} else {
reject("Ошибка выполнения");
}
});
resolve и reject — это функции, предоставляемые JavaScript для управления состоянием промиса.
then,
catch и finallyПосле создания промиса можно подключить обработчики с помощью методов
then, catch и finally.
promise.then(
result => console.log("Успех:", result),
error => console.log("Ошибка:", error)
);
promise
.then(result => console.log("Успех:", result))
.catch(error => console.log("Ошибка:", error));
promise.finally(() => console.log("Операция завершена"));
Одним из ключевых преимуществ промисов является возможность создания цепочек, где результат одного промиса передаётся следующему.
fetch("https://api.example.com/data")
.then(response => response.json())
.then(data => {
console.log("Данные:", data);
return data.items;
})
.then(items => {
console.log("Элементы:", items);
})
.catch(error => {
console.error("Ошибка при получении данных:", error);
});
Каждый вызов then возвращает новый промис, что позволяет
строить длинные последовательности обработки асинхронных операций.
С появлением async/await промисы стали ещё более
удобными для работы. Асинхронная функция всегда возвращает промис:
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
console.log("Данные:", data);
} catch (error) {
console.error("Ошибка:", error);
} finally {
console.log("Запрос завершён");
}
}
await приостанавливает выполнение функции до завершения
промиса.try/catch позволяет обрабатывать ошибки
асинхронного кода аналогично синхронному.finally выполняется в любом случае, точно так же, как и
с обычными промисами.JavaScript предоставляет несколько полезных статических методов для работы с множеством промисов:
Promise.all([fetch(url1), fetch(url2)])
.then(([res1, res2]) => console.log("Два ответа:", res1, res2))
.catch(error => console.error("Ошибка одного из промисов:", error));
Promise.allSettled([fetch(url1), fetch(url2)])
.then(results => console.log("Состояния промисов:", results));
Promise.race([fetch(url1), fetch(url2)])
.then(result => console.log("Первый результат:", result))
.catch(error => console.error("Первая ошибка:", error));
Promise.any([fetch(url1), fetch(url2)])
.then(result => console.log("Первый успешный:", result))
.catch(error => console.error("Все промисы отклонены:", error));
Стандартные промисы не имеют встроенной функции отмены. Для управления асинхронными операциями часто используют:
const controller = new AbortController();
const signal = controller.signal;
fetch("https://api.example.com/data", { signal })
.then(response => response.json())
.then(data => console.log("Данные:", data))
.catch(error => console.error("Ошибка или отмена:", error));
// Отмена запроса
controller.abort();
Promise.allSettled для параллельных операций
с независимыми результатами.async/await для читаемости.Эффективное использование промисов позволяет писать асинхронный код, который легко читается, поддерживается и масштабируется.