Асинхронность: промисы
Промис — объект, представляющий результат асинхронной операции. Может быть в трёх состояниях: pending, fulfilled, rejected.
Создание
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('готово'), 1000);
});
then / catch / finally
promise
.then((value) => console.log(value))
.catch((error) => console.error(error))
.finally(() => console.log('завершено'));
Цепочка
fetch('/api/user')
.then((res) => res.json())
.then((user) => console.log(user))
.catch((err) => console.error(err));
Состояния
- pending — ожидание
- fulfilled — выполнено с результатом
- rejected — отклонено с ошибкой
После перехода в fulfilled или rejected промис не меняется.
Комбинаторы
Promise.all
Ждёт все, возвращает массив. Если один упадёт — весь промис упадёт.
const [a, b, c] = await Promise.all([
fetch('/a').then((r) => r.json()),
fetch('/b').then((r) => r.json()),
fetch('/c').then((r) => r.json()),
]);
Promise.allSettled
Ждёт все, возвращает результаты с status:
const results = await Promise.allSettled([p1, p2]);
// [{ status: 'fulfilled', value }, { status: 'rejected', reason }]
Promise.race
Первый завершённый (успех или ошибка):
const result = await Promise.race([fetch('/fast'), fetch('/slow')]);
Promise.any
Первый успешный:
const result = await Promise.any([p1, p2]);
Если все упадут — AggregateError.
Асинхронная функция
async function loadUser(id) {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
async всегда возвращает промис.
await
const user = await loadUser(1);
Приостанавливает выполнение функции до разрешения промиса.
Обработка ошибок
async function load() {
try {
const data = await fetchData();
return data;
} catch (error) {
console.error(error);
throw error;
} finally {
console.log('готово');
}
}
Последовательное vs параллельное
Последовательно (медленнее):
const a = await fetchA();
const b = await fetchB();
Параллельно:
const [a, b] = await Promise.all([fetchA(), fetchB()]);
Создание промиса
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
await delay(1000);
Промисификация
function readFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
}
Утечки
Если промис отклонён и не обработан — UnhandledPromiseRejection. Всегда добавляй catch или try/catch.
Итоги
- Промис — результат асинхронной операции
then,catch,finallyasync/await— синтаксический сахарPromise.allдля параллельностиallSettledкогда нужны все результаты- Обрабатывай ошибки