Как пробросить глобальные переменные без store?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Чем будешь пользоваться для выполнения запросов нескольких Promise?
Выполнение нескольких асинхронных операций одновременно — типичная задача в веб-разработке. JavaScript предоставляет несколько способов работы с Promise, каждый из которых подходит для разных сценариев.
1. Promise.all() — Ожидание всех промисов
Promise.all() ждет, пока все промисы выполнятся успешно. Если хотя бы один отклонится, весь результат будет ошибкой.
const promise1 = fetch("/api/users").then((r) => r.json());
const promise2 = fetch("/api/posts").then((r) => r.json());
const promise3 = fetch("/api/comments").then((r) => r.json());
Promise.all([promise1, promise2, promise3])
.then(([users, posts, comments]) => {
console.log("All data loaded:", { users, posts, comments });
})
.catch((err) => {
console.error("One of the requests failed:", err);
});
// С async/await
async function loadAllData() {
try {
const [users, posts, comments] = await Promise.all([
fetch("/api/users").then((r) => r.json()),
fetch("/api/posts").then((r) => r.json()),
fetch("/api/comments").then((r) => r.json()),
]);
return { users, posts, comments };
} catch (err) {
console.error("Failed to load data:", err);
}
}
2. Promise.allSettled() — Ожидание всех с результатами
В отличие от Promise.all(), этот метод ждет выполнения всех промисов, даже если некоторые отклонены. Возвращает массив объектов {status, value/reason}.
const promises = [
fetch("/api/users").then((r) => r.json()),
fetch("/api/broken").then((r) => r.json()), // Может ошибиться
fetch("/api/posts").then((r) => r.json()),
];
Promise.allSettled(promises)
.then((results) => {
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Promise ${index} succeeded:`, result.value);
} else {
console.log(`Promise ${index} failed:`, result.reason);
}
});
});
// С async/await и обработкой ошибок
async function loadDataWithFallback() {
const results = await Promise.allSettled([
fetch("/api/users").then((r) => r.json()),
fetch("/api/posts").then((r) => r.json()),
]);
const users = results[0].status === "fulfilled" ? results[0].value : [];
const posts = results[1].status === "fulfilled" ? results[1].value : [];
return { users, posts };
}
3. Promise.race() — Первый завершенный промис
Этот метод возвращает результат первого завершенного промиса, остальные игнорируются.
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), 5000)
);
const fetchData = fetch("/api/data").then((r) => r.json());
Promise.race([fetchData, timeout])
.then((data) => console.log("Data loaded:", data))
.catch((err) => console.error("Request timeout or failed:", err));
// Практический пример: загрузка с несколькими источниками
function loadFromFastestSource(sources) {
const promises = sources.map((source) => fetch(source).then((r) => r.json()));
return Promise.race(promises);
}
const data = await loadFromFastestSource([
"https://primary-cdn.com/data",
"https://backup-cdn.com/data",
]);
4. Promise.any() — Первый успешный промис
Возвращает результат первого успешно выполненного промиса. Если все отклонены, выбрасывает ошибку.
const source1 = fetch("https://api1.com/data").then((r) => r.json());
const source2 = fetch("https://api2.com/data").then((r) => r.json());
const source3 = fetch("https://api3.com/data").then((r) => r.json());
Promise.any([source1, source2, source3])
.then((data) => console.log("Data from first successful source:", data))
.catch((err) => console.error("All sources failed:", err));
5. Async/Await — Современный подход
// Последовательное выполнение (ждет каждый)
async function loadSequential() {
const users = await fetch("/api/users").then((r) => r.json());
const posts = await fetch("/api/posts").then((r) => r.json());
return { users, posts };
}
// Параллельное выполнение (одновременно)
async function loadParallel() {
const [users, posts] = await Promise.all([
fetch("/api/users").then((r) => r.json()),
fetch("/api/posts").then((r) => r.json()),
]);
return { users, posts };
}
6. Практический пример в React компоненте
function DataContainer() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadData() {
try {
setLoading(true);
const [users, posts, comments] = await Promise.all([
fetch("/api/users").then((r) => r.json()),
fetch("/api/posts").then((r) => r.json()),
fetch("/api/comments").then((r) => r.json()),
]);
setData({ users, posts, comments });
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
loadData();
}, []);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h2>Users: {data.users.length}</h2>
<h2>Posts: {data.posts.length}</h2>
<h2>Comments: {data.comments.length}</h2>
</div>
);
}
Сравнительная таблица
| Метод | Что делает | Когда использовать |
|---|---|---|
| Promise.all() | Ждет все, fails если один ошибку | Нужны все данные обязательно |
| Promise.allSettled() | Ждет все, возвращает результаты | Нужны данные, но допускаются ошибки |
| Promise.race() | Возвращает первый | Timeout, гонка источников |
| Promise.any() | Возвращает первый успешный | Несколько резервных источников |
Лучшие практики
- Используй Promise.all() для независимых операций
- Async/await более читаемый код, чем цепочки .then()
- Всегда обрабатывай ошибки через try/catch
- Используй Promise.allSettled() если нужны все результаты
- Избегай вложенных Promise — используй async/await
Выбор правильного метода зависит от требований твоего приложения и обработки ошибок.