Події в JavaScript: як працює Event Loop
JavaScript, Веб-розробка ·JavaScript — це мова програмування з однопотоковою природою, але при цьому вона вміє обробляти асинхронні операції. Це можливо завдяки Event Loop — механізму, який дозволяє JavaScript виконувати код без блокування основного потоку. У цьому дописі розглянемо, як саме працює Event Loop, чому він важливий і як правильно використовувати його особливості.
Основи роботи Event Loop
В основі роботи Event Loop лежать три основні складові:
- Call Stack (стек викликів) — місце, де виконуються синхронні функції.
- Task Queue (черга завдань) — список колбеків, які чекають своєї черги для виконання.
- Microtask Queue (черга мікрозавдань) — черга для Promise та інших мікрозавдань.
Розглянемо приклад:
console.log("Початок");
setTimeout(() => {
console.log("setTimeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise");
});
console.log("Кінець");
Очікуваний порядок виконання:
console.log("Початок")— виводиться одразу.setTimeoutвідкладає виконання колбека в Task Queue.Promise.resolve().then(...)додає колбек у Microtask Queue.console.log("Кінець")— виводиться одразу.- Після завершення синхронного коду Event Loop перевіряє Microtask Queue — виконується
console.log("Promise"). - Лише після цього виконується колбек з Task Queue —
console.log("setTimeout").
Результат у консолі буде:
Початок
Кінець
Promise
setTimeout
Чому setTimeout(..., 0) не виконується миттєво?
setTimeout(..., 0) не означає, що функція виконається одразу. Він додає колбек у Task Queue, який обробляється лише після виконання всіх мікрозавдань.
Приклад, де це добре видно:
setTimeout(() => console.log("setTimeout"), 0);
for (let i = 0; i < 1e9; i++) {} // Блокуємо основний потік
console.log("Кінець циклу");
Тут setTimeout затримується, поки цикл не завершиться, навіть якщо стоїть 0 мілісекунд.
Використання queueMicrotask
Якщо потрібно виконати код раніше, ніж setTimeout, можна скористатися queueMicrotask:
queueMicrotask(() => console.log("Мікрозавдання"));
console.log("Основний код");
Результат:
Основний код
Мікрозавдання