Skip to main content

Що таке event loop?

Event Loop (цикл подій) - це механізм всередині рушія JavaScript, який керує виконанням коду, обробкою асинхронних операцій та взаємодією між Call Stack (стеком викликів) і чергами завдань (task queues).

Саме event loop робить JavaScript асинхронним і неблокуючим, навіть попри те, що мова сама по собі однопотокова.

Коротко

Event Loop - це "організатор", який вирішує, яке завдання виконується зараз, а яке почекає, щоб не блокувати основний потік.

Основні учасники

Щоб зрозуміти Event Loop, потрібно знати три структури:

  1. Call Stack - стек викликів (де виконується поточний код, наприклад функції та вирази).
  2. Task Queue / Callback Queue - черга макротасків (таймери, події, setTimeout, setInterval, I/O).
  3. Microtask Queue - черга мікротасків (Promise.then(), queueMicrotask(), process.nextTick() у Node.js).
  4. Event Loop - "петля", яка стежить:
  • якщо стек порожній → бере завдання з черги мікротасків;
  • якщо вона порожня → бере завдання з черги макротасків.

Як працює Event Loop (по кроках)

  1. JS виконує синхронний код (все, що зверху вниз).
  2. Коли зустрічається асинхронна операція - вона відправляється у зовнішні Web API (наприклад, таймер, fetch).
  3. Коли операція завершується, її колбек потрапляє у чергу завдань.
  4. Коли Call Stack порожній, Event Loop бере завдання з черги і кладе його в стек для виконання.
  5. Після виконання всіх мікротасків, Event Loop переходить до наступної макротаски.

Це відбувається постійно, у "нескінченному циклі".

Візуально

javascript
┌────────────────────┐ │ Call Stack │ ← виконує поточний код └─────────▲──────────┘ │ │ (порожній?) ▼ ┌────────────────────┐ │ Microtask Queue │ ← Promise, queueMicrotask └─────────▲──────────┘ │ │ (порожня?) ▼ ┌────────────────────┐ │ Task Queue │ ← setTimeout, setInterval, I/O └─────────▲──────────┘ │ │ ▼ Event Loop перевіряє черги і переносить завдання в стек

Приклад з setTimeout та Promise

javascript
console.log('1'); setTimeout(() => console.log('2'), 0); Promise.resolve().then(() => console.log('3')); console.log('4');

Вивід:

javascript
1 4 3 2

Чому?

  1. Спочатку виконується синхронний код (1, 4);
  2. Promise (.then) потрапляє у мікротаски;
  3. setTimeout потрапляє у макротаски;
  4. Event Loop спочатку виконує всі мікротаски (3), потім бере наступну макротаску (2).

Приклад із "зависанням" Event Loop

javascript
setTimeout(() => console.log('2'), 0); while (true) {} // нескінченний цикл

Event Loop ніколи не дійде до setTimeout, тому що стек ніколи не звільниться. Асинхронні завдання виконуються тільки коли стек порожній.

Різниця між макро- та мікротасками

Тип завданняПрикладиКоли виконується
МікротаскиPromise.then, queueMicrotaskОдразу після поточного коду і перед наступною макротаскою
МакротаскиsetTimeout, setInterval, fetch, I/O, DOM eventsПісля всіх мікротасків

Тобто мікротаски мають вищий пріоритет.

У браузері vs у Node.js

СередовищеОсобливості Event Loop
БраузерУ Web APIs є таймери, fetch, DOM events
Node.jsЄ свої черги (phases): timers, I/O, check, close, nextTick тощо

Але в обох випадках ідея одна - один потік, асинхронність через event loop.

ІТОГ

КомпонентПризначення
Call StackВиконує поточний код
Web APIsВідпрацьовують асинхронні операції
Task QueueЗберігає колбеки макротасків
Microtask QueueЗберігає проміси та мікрочергу
Event LoopПереміщує готові завдання з черг у стек

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.