Почему Node.js однопоточный

Node.js часто называют однопоточной средой выполнения, и это правда — но с нюансами. Чтобы понять почему, важно вспомнить, как работает JavaScript и сам механизм event loop.

Почему один поток?

  • Исторически JavaScript в браузере выполняется в одном потоке — чтобы не усложнять работу с DOM и избежать гонок данных.
  • Node.js унаследовал этот принцип: один поток для выполнения кода JavaScript.

Это значит, что одновременно выполняется только один участок JS-кода.

Но как тогда обрабатываются тысячи запросов?

Здесь вступает в игру event loop и асинхронная модель ввода-вывода:

  • Системные операции (файлы, сеть, БД) выполняются в фоновом режиме (через libuv и пул потоков C++).
  • Node.js не ждёт, пока операция завершится — он ставит callback или Promise в очередь.
  • Когда операция готова, event loop вызывает соответствующий обработчик.

Таким образом, даже на одном потоке Node.js может обслуживать тысячи соединений.

Важные нюансы

  • CPU-bound задачи (сложные вычисления) блокируют event loop и замедляют весь сервер.
  • Для тяжёлых задач используют worker threads или вынесение вычислений в отдельные сервисы.
  • Для I/O-bound приложений (API, web-сервисы, чаты) Node.js идеален.

Итог

Node.js однопоточный для JavaScript-кода, но под капотом у него есть асинхронные механизмы и пул потоков для тяжёлых операций.
Именно это сочетание делает его быстрым и эффективным для сетевых приложений.