JavaScript & TypeScriptМодуль 5: Асинхронность
Методы Promise
Promise.all, allSettled, race и any
Цель урока
В этом уроке ты научишься:
- Выполнять несколько промисов параллельно
- Выбирать стратегию обработки результатов
- Оптимизировать асинхронные операции
Promise.all
Ждёт выполнения всех промисов. Если один отклонён — весь результат отклонён.
let promise1 = Promise.resolve(1);
let promise2 = Promise.resolve(2);
let promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then(results => console.log(results))
.catch(error => console.log(error));
// [1, 2, 3]При ошибке
let promise1 = Promise.resolve(1);
let promise2 = Promise.reject("Ошибка");
let promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then(results => console.log(results))
.catch(error => console.log(error));
// "Ошибка"Практический пример
async function loadUserData(userId) {
let [user, posts, comments] = await Promise.all([
fetch(`/api/users/${userId}`).then(r => r.json()),
fetch(`/api/posts?userId=${userId}`).then(r => r.json()),
fetch(`/api/comments?userId=${userId}`).then(r => r.json())
]);
return { user, posts, comments };
}Promise.allSettled
Ждёт выполнения всех промисов, независимо от результата.
let promise1 = Promise.resolve(1);
let promise2 = Promise.reject("Ошибка");
let promise3 = Promise.resolve(3);
Promise.allSettled([promise1, promise2, promise3])
.then(results => console.log(results));
// [
// { status: "fulfilled", value: 1 },
// { status: "rejected", reason: "Ошибка" },
// { status: "fulfilled", value: 3 }
// ]Фильтрация результатов
Promise.allSettled(promises)
.then(results => {
let successful = results
.filter(r => r.status === "fulfilled")
.map(r => r.value);
let failed = results
.filter(r => r.status === "rejected")
.map(r => r.reason);
console.log("Успешные:", successful);
console.log("Неудачные:", failed);
});Promise.race
Возвращает результат первого завершённого промиса (успех или ошибка).
let slow = new Promise(resolve => setTimeout(() => resolve("Медленный"), 2000));
let fast = new Promise(resolve => setTimeout(() => resolve("Быстрый"), 1000));
Promise.race([slow, fast])
.then(result => console.log(result));
// "Быстрый"Таймаут запроса
function fetchWithTimeout(url, timeout) {
let timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject("Таймаут"), timeout);
});
return Promise.race([fetch(url), timeoutPromise]);
}
fetchWithTimeout("/api/data", 5000)
.then(response => response.json())
.catch(error => console.log(error));Promise.any
Возвращает первый успешный результат. Отклоняется только если все отклонены.
let promise1 = Promise.reject("Ошибка 1");
let promise2 = Promise.resolve("Успех");
let promise3 = Promise.reject("Ошибка 2");
Promise.any([promise1, promise2, promise3])
.then(result => console.log(result));
// "Успех"Все отклонены
let promise1 = Promise.reject("Ошибка 1");
let promise2 = Promise.reject("Ошибка 2");
Promise.any([promise1, promise2])
.catch(error => console.log(error));
// AggregateError: All promises were rejectedРезервные источники
function fetchFromMultipleSources(urls) {
let fetches = urls.map(url => fetch(url).then(r => r.json()));
return Promise.any(fetches);
}
fetchFromMultipleSources([
"https://api1.example.com/data",
"https://api2.example.com/data",
"https://api3.example.com/data"
])
.then(data => console.log("Получено:", data))
.catch(() => console.log("Все источники недоступны"));Сравнение
| Метод | Успех | Ошибка |
|---|---|---|
all | Все успешны | Первая ошибка |
allSettled | Все завершены | Никогда |
race | Первый завершён | Первая ошибка |
any | Первый успех | Все ошибки |
Практика
Задание 1: Promise.all
Задача: Загрузи данные параллельно.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
[1,2,3]
Задание 2: Promise.allSettled
Задача: Обработай смешанные результаты.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
Успешных: 2 Неудачных: 1
Задание 3: Promise.race
Задача: Реализуй таймаут.
Loading...
Ваш вывод:
Проверь себя
- Когда использовать
Promise.allvsPromise.allSettled? - Чем
Promise.raceотличается отPromise.any? - Как реализовать таймаут для запроса?