Як працює event loop у Node.js?
Цикл подій Node.js
Цикл подій є серцем Node.js. Він дозволяє Node.js виконувати неблокуючий ввід/вивід незважаючи на те, що працює в однопоточному режимі — шляхом перенесення операцій на ОС та пул потоків libuv, а потім виконуючи зворотні виклики, коли вони завершуються.
Фази циклу подій
Цикл подій обробляє зворотні виклики у строгому порядку фаз:
┌───────────────────────────┐
┌─>│ таймери │ ← зворотні виклики setTimeout, setInterval
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ очікуючі зворотні │ ← зворотні виклики I/O, відкладені на наступний цикл
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ простою, підготовка │ ← лише для внутрішнього використання
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ опитування │ ← отримання нових подій I/O
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ перевірка │ ← зворотні виклики setImmediate
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ зворотні виклики │ ← socket.on('close', ...)
└───────────────────────────┘Між кожною фазою Node.js виконує мікрозавдання:
- Зворотні виклики
process.nextTick()(найвищий пріоритет) - Зворотні виклики Promise (
.then(),async/await)
Приклад порядку виконання
console.log('1: start');
setTimeout(() => console.log('4: setTimeout'), 0);
setImmediate(() => console.log('5: setImmediate'));
Promise.resolve().then(() => console.log('3: Promise'));
process.nextTick(() => console.log('2: nextTick'));
console.log('1: end');
// Вивід:
// 1: start
// 1: end
// 2: nextTick
// 3: Promise
// 4: setTimeout
// 5: setImmediateДеталі фаз
1. Таймери
Виконує зворотні виклики, заплановані за допомогою setTimeout() та setInterval(), термін затримки яких минув.
2. Опитування
Отримує нові події I/O. Якщо нічого не поставлено в чергу, він чекає тут на зворотні виклики I/O.
3. Перевірка
Виконує зворотні виклики setImmediate() — завжди після подій I/O.
Мікрозавдання проти макрозавдань
| Тип | Приклади | Пріоритет |
|---|---|---|
| Мікрозавдання | process.nextTick, Promises | Найвищий — виконується між кожною фазою |
| Макрозавдання | setTimeout, setInterval, I/O | Нижчий — виконується в фазах циклу подій |
Ключове зауваження
Цикл подій дозволяє Node.js обробляти тисячі одночасних з'єднань без створення потоку для кожного з'єднання. Якщо ви уникатимете блокування основного потоку (наприклад, синхронними викликами fs або важкими циклами CPU), Node.js залишатиметься високопродуктивним.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.