Ответ вслух Middle Event loop и libuv спрашивают часто обновлено

Объясни event loop в Node.js

Вопрос

Объясни, как устроен event loop в Node.js и почему однопоточный сервер выдерживает тысячи соединений.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Node выполняет JavaScript в одном потоке, но почти никогда не ждёт. Когда код читает файл или делает сетевой запрос, он отдаёт операцию libuv и регистрирует колбэк.

Что должно прозвучать в ответе

  • JS выполняется в одном потоке, ввод-вывод неблокирующий: колбэк регистрируется, ответ приходит позже

  • Цикл и асинхронность даёт libuv: сеть через epoll/kqueue/IOCP, файлы, DNS и crypto через пул потоков (4 по умолчанию)

  • Фазы: timers, pending, poll, check (setImmediate), close callbacks

  • Между колбэками опустошаются очереди process.nextTick и микрозадач промисов

  • Сервер масштабируется, пока колбэки короткие; CPU-работа блокирует всех

  • Тяжёлое выносить в worker_threads, асинхронные API, дробить работу

Что могут спросить следом

  • Почему setImmediate внутри readFile срабатывает раньше setTimeout(0)?
  • Как заметить, что event loop заблокирован в проде?
  • Чем event loop Node отличается от браузерного?

Разбор

Node выполняет JavaScript в одном потоке, но почти никогда не ждёт. Когда код читает файл или делает сетевой запрос, он отдаёт операцию libuv и регистрирует колбэк. Сеть libuv обслуживает через системные механизмы вроде epoll, а файлы, DNS и тяжёлую криптографию через пул потоков, по умолчанию четыре.

Сам цикл проходит фазы: таймеры, отложенные колбэки, poll, где он ждёт и обрабатывает ввод-вывод, check с setImmediate и колбэки закрытия. После каждого колбэка Node опустошает очередь process.nextTick и очередь промисов.

Поэтому один поток держит тысячи соединений: на каждое тратится только короткое время обработки. Обратная сторона: если колбэк долго считает, например синхронно хеширует пароль или парсит огромный JSON, стоят все. Такое я выношу в worker_threads или использую асинхронные версии API. В проде блокировки видно по метрике задержки цикла, например через perf_hooks.monitorEventLoopDelay.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме