JavaScript работает на одном потоке — это означает, что у него есть один call stack и он может выполнять только одну операцию за раз. Несмотря на это, он эффективно обрабатывает асинхронную работу через набор скоординированных механизмов.
Когда движок встречает асинхронный API вроде setTimeout, fetch или обработчики событий DOM, он делегирует их браузеру или рантайму (Web APIs). JavaScript не ждёт их завершения — он продолжает выполнять оставшийся синхронный код.
setTimeout, fetch, DOM events → обрабатываются браузером/Node.js рантаймом
После завершения их колбэки попадают в очередь, готовые к обработке.
Есть две отдельные очереди с разными приоритетами:
Promise.then(), queueMicrotask() и MutationObserver. Они выполняются сразу же после завершения текущей задачи.setTimeout, setInterval и событий DOM. Они выполняются после полной очистки очереди микротасков.Event loop постоянно следит за call stack-ом и очередями:
console.log("start");
setTimeout(() => console.log("timeout"), 0);
Promise.resolve().then(() => console.log("promise"));
console.log("end");
// Вывод: start → end → promise → timeout
"promise" выводится перед "timeout", потому что микротаски имеют приоритет перед макротасками, даже когда задержка setTimeout равна 0.Microtask очередь имеет более высокий приоритет, чем callback очередь, поэтому все microtasks выполняются перед обработкой любых macrotask callbacks, независимо от того, когда они были добавлены в очередь.
Новый — ещё не проверен сообществом
Вы