Используй событийный цикл, правильно распараллеливай промисы и сделай обработку асинхронных ошибок надёжной.
Открыть этот урок в KodokonМодель выполнения опирается на очередь макрозадач (setTimeout, ввод-вывод) и очередь микрозадач (.then, await, queueMicrotask). После каждой задачи движок полностью опустошает очередь микрозадач, прежде чем идти дальше. Прямое следствие: разрешённый промис всегда выполнится раньше setTimeout(fn, 0), а слишком длинная цепочка микрозадач может подвесить отрисовку так же надёжно, как синхронный цикл.
console.log("start");
setTimeout(() => console.log("macrotask"), 0);
Promise.resolve().then(() => console.log("microtask"));
console.log("end");
// start, end, microtask, macrotaskasync/await - это синтаксический сахар поверх промисов, но он прячет ловушку производительности: каждый await внутри цикла сериализует операции. Если запросы независимы, сначала запусти их все, а потом дождись пачку через Promise.all. Для трёх запросов по 100 мс последовательная версия стоит 300 мс, параллельная - 100 мс.
const fetchUser = (id) => new Promise((res) => {
setTimeout(() => res({ id }), 100);
});
async function loadSequential(ids) {
const users = [];
for (const id of ids) {
users.push(await fetchUser(id)); // ~100 ms each
}
return users;
}
async function loadParallel(ids) {
return Promise.all(ids.map(fetchUser)); // ~100 ms total
}Выбирай комбинатор под нужный тебе контракт отказа: Promise.all отклоняется на первой ошибке (всё или ничего), allSettled дожидается всех и описывает каждый исход, race берёт первое завершение (успех или ошибку - удобно для таймаута), any берёт первый успех и отклоняется только если провалилось всё. Для дашборда, который обязан показать частичные результаты, allSettled почти всегда правильный выбор.
const tasks = [
Promise.resolve("profile loaded"),
Promise.reject(new Error("network unavailable")),
];
const results = await Promise.allSettled(tasks);
for (const r of results) {
if (r.status === "fulfilled") {
console.log("success:", r.value);
} else {
console.error("failure:", r.reason.message);
}
}console.log, колбэк Promise.resolve().then и колбэк setTimeout(fn, 0)?try { doAsync(); } catch (e) {} без await не ловит отклонение от doAsync?