Коротка відповідь
juniorEvent loop — це механізм, що обробляє асинхронні задачі у JavaScript‑рушії. Він чергує колбеків з call stack, виконуючи їх по завершенню синхронного коду. Через event loop можна об’єднати таймери, I/O та проміси в однорідний цикл.
Повне пояснення
Що це і навіщо Event loop — ядро асинхронності в JavaScript‑рушії. Він дозволяє виконувати неблокуючі операції, не зупиняючи головний потік.
Ключові принципи
- Call stack (стек викликів) обробляє синхронний код.
- Task queue (очередь задач) зберігає колбеки, що готові до виконання.
- Microtask queue (очередь мікротасків) обробляється після кожного синхронного блоку.
Як це працює
- Синхронний код виконується у call stack.
- Після завершення стеку, рушій перевіряє microtask queue; якщо є задачі – обробляє їх.
- Якщо microtasks порожня, рушій переходить до task queue і виконує першу задачу.
- Процес повторюється, забезпечуючи реактивність.
Практика і реалізація
setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('sync');
// Output: sync, promise, timeout
Тестування
import { test } from 'vitest';
test('event loop order', async () => {
const logs: string[] = [];
setTimeout(() => logs.push('timeout'), 0);
Promise.resolve().then(() => logs.push('promise'));
logs.push('sync');
await new Promise(r => setTimeout(r, 10));
expect(logs).toEqual(['sync', 'promise', 'timeout']);
});
Особливості в контексті JS Core
- Event loop працює однопоточно, тому важливо не блокувати стек.
- Microtasks мають пріоритет над task queue, що впливає на порядок виконання.
- Таймери (setTimeout/interval) додаються до task queue після заданого часу.
Оптимізація та типові помилки
- Не використовуйте довгі синхронні цикли; вони блокують event loop.
- Уникайте нескінченних рекурсій у колбеках, що призведе до стек overflow.
- Перевіряйте порядок виконання при використанні Promise, async/await та setTimeout.
Часті помилки (8)
- Очікування
setTimeout(..., 0)як миттєвого виклику – це task queue. - Відсутність
awaitу async функціях, що призводить до непередбачуваного порядку. - Використання
setImmediate(Node.js) замість microtasks. - Блокування стеку через довгий цикл
while. - Неочікувані колбеки в
process.nextTick(Node.js) – вони виконуються перед microtasks. - Перевантаження task queue великою кількістю таймерів.
- Залишені
setTimeoutбез очищення, що створює memory leak. - Виклик
Promise.resolve().then()у циклі без очікування, що створює мікротаски в нескінченності.
Cheatsheet
- call stack → microtask queue → task queue → repeat.
Promise.then→ microtasks.setTimeout/interval→ task queue.
Follow‑up питання
- Як microtasks впливають на порядок виконання колбеків?
- Що відбувається, якщо в microtask queue додати ще один колбек?
- Чому
setImmediateне є частиною стандартного Event loop в браузерах?