Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Promise.all: параллельное выполнение Promise'ов
Что такое Promise.all
Promise.all это метод, который принимает массив Promise'ов и возвращает новый Promise. Результат:
- Успех: все Promise'ы resolve — возвращает массив результатов
- Ошибка: хотя бы один Promise reject — весь Promise.all reject'ится
Синтаксис и примеры
// Базовый пример
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(results => {
console.log(results); // [1, 2, 3]
});
// С async/await
const results = await Promise.all([p1, p2, p3]);
console.log(results); // [1, 2, 3]
Практический пример: Загрузка данных из разных API
// Без Promise.all — последовательно (медленно)
const getUserProfile = async (userId) => {
const user = await fetch(`/api/users/${userId}`).then(r => r.json()); // 200ms
const posts = await fetch(`/api/posts/${userId}`).then(r => r.json()); // 200ms
const friends = await fetch(`/api/friends/${userId}`).then(r => r.json()); // 200ms
// Total: 600ms
return { user, posts, friends };
};
// С Promise.all — параллельно (быстро)
const getUserProfileFast = async (userId) => {
const [user, posts, friends] = await Promise.all([
fetch(`/api/users/${userId}`).then(r => r.json()),
fetch(`/api/posts/${userId}`).then(r => r.json()),
fetch(`/api/friends/${userId}`).then(r => r.json())
]);
// Total: 200ms (самый долгий запрос)
return { user, posts, friends };
};
Обработка ошибок
// Если один Promise reject'ится — весь Promise.all reject'ится
const p1 = Promise.resolve(1);
const p2 = Promise.reject(new Error('Oops!'));
const p3 = Promise.resolve(3);
try {
const results = await Promise.all([p1, p2, p3]);
console.log(results); // Это НЕ выполнится
} catch (error) {
console.error(error.message); // "Oops!"
}
Реальный пример: Инициализация приложения
const initializeApp = async () => {
try {
const [db, cache, config] = await Promise.all([
connectToDatabase(), // 500ms
initializeRedis(), // 200ms
loadConfiguration() // 100ms
]);
// Total: 500ms (самый долгий)
console.log('App initialized');
return { db, cache, config };
} catch (error) {
console.error('Initialization failed:', error);
process.exit(1);
}
};
Promise.all с разными типами данных
const mixed = await Promise.all([
Promise.resolve(1),
'string', // не Promise, используется как есть
new Promise(resolve => setTimeout(() => resolve('delayed'), 100)),
42 // не Promise
]);
console.log(mixed); // [1, 'string', 'delayed', 42]
Promise.allSettled — когда ошибка не критична
// Promise.all — если один упал, все упали
const all = await Promise.all([
fetchUser(), // resolve
fetchPosts(), // reject
fetchComments() // resolve (но не выполнится)
]);
// Ошибка!
// Promise.allSettled — выполняет ВСЕ и возвращает результаты
const results = await Promise.allSettled([
fetchUser(), // resolve
fetchPosts(), // reject
fetchComments() // resolve (выполнится)
]);
// Результат:
[
{ status: 'fulfilled', value: {...} },
{ status: 'rejected', reason: Error(...) },
{ status: 'fulfilled', value: [...] }
]
// Обработка результатов
const successful = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
Promise.race — кто первый выполнится
// Promise.race возвращает результат первого выполненного Promise'а
const fastest = await Promise.race([
fetchFromServer1(), // 300ms
fetchFromServer2(), // 200ms (первый!)
fetchFromServer3() // 400ms
]);
console.log(fastest); // Результат от Server2
// Практический пример: timeout
const fetchWithTimeout = (url, timeout = 5000) => {
return Promise.race([
fetch(url),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeout)
)
]);
};
const data = await fetchWithTimeout('/api/data', 3000); // Если дольше 3 сек — ошибка
Promise.any — хотя бы один успех
// Promise.any — возвращает первый успешный результат
const first = await Promise.any([
Promise.reject('Server 1 down'),
Promise.resolve('Server 2 up'), // первый успешный
Promise.reject('Server 3 down')
]);
console.log(first); // 'Server 2 up'
// Если все reject'ятся — ошибка
const none = await Promise.any([
Promise.reject('A'),
Promise.reject('B')
]);
// AggregateError: All promises were rejected
Отличия методов параллельного выполнения
Promise.all:
- Возвращает результаты всех Promise'ов в массиве
- Если один reject'ится — весь all reject'ится
- Использование: когда все результаты нужны
Promise.allSettled:
- Возвращает статусы всех Promise'ов (fulfilled/rejected)
- Не зависит от ошибок других
- Использование: когда нужно обработать все, даже ошибки
Promise.race:
- Возвращает результат первого выполненного Promise
- Использование: timeout, выбор самого быстрого
Promise.any:
- Возвращает результат первого успешного Promise
- Использование: redundancy, fail-over
Примеры из production кода
// 1. Инициализация сервисов
const startServer = async () => {
const [database, cache, messageQueue] = await Promise.all([
db.connect(),
redis.connect(),
rabbitmq.connect()
]);
};
// 2. Загрузка данных в dashboards
const getDashboardData = async (userId) => {
const [stats, analytics, recommendations] = await Promise.all([
getUserStats(userId),
getAnalytics(userId),
getRecommendations(userId)
]);
return { stats, analytics, recommendations };
};
// 3. Batch операции
const updateMultipleUsers = async (userIds) => {
const updatePromises = userIds.map(id =>
updateUser(id, { lastSeen: Date.now() })
);
await Promise.all(updatePromises);
};
// 4. С обработкой ошибок
const loadUserData = async (userId) => {
try {
const [user, profile, settings] = await Promise.all([
getUserFromDB(userId),
getUserProfile(userId),
getUserSettings(userId)
]);
return { user, profile, settings };
} catch (error) {
if (error.code === 'USER_NOT_FOUND') {
return null;
}
throw error;
}
};
Как НЕ использовать
// ❌ ПЛОХО: создавать Promise'ы после Promise.all
for (let i = 0; i < users.length; i++) {
const user = await getUser(users[i]); // Последовательно!
}
// ✅ ХОРОШО: создавать Promise'ы до Promise.all
const userPromises = users.map(id => getUser(id));
const allUsers = await Promise.all(userPromises); // Параллельно
// ❌ ПЛОХО: забывать await
Promise.all([...]) // Не дожидаемся результата!
// ✅ ХОРОШО
await Promise.all([...]) // Ждём результата
Заключение
Promise.all это фундаментальная концепция асинхронного программирования:
- Для параллельного выполнения независимых операций
- Существенно ускоряет приложение
- Нужно правильно обрабатывать ошибки
- Есть варианты (allSettled, race, any) для разных случаев