Node.js, цикл событий и многопоточность

Вы все знаете это или похожее предложение: Node.js — это однопоточная, неблокирующая асинхронная параллельная среда выполнения.

Но что, если я скажу вам, что на самом деле это не так?

Удивлен? Ну, вот тут люди могут спорить об этом, и это здорово. Но на самом деле ваш JavaScript/TypeScript-код можно запускать в несколько потоков, и на самом деле он делает это сам по себе благодаря Node.js, а точнее — благодаря Libuv.

Что такое Либув?

Опытные разработчики Node.js, вероятно, знают, что такое Libuv, но все же позвольте мне объяснить.

Libuv — это библиотека, полностью написанная на C. Она фокусируется на асинхронных операциях ввода-вывода, таких как файловая система, сеть, криптография и т. д. Она переносит пул событий, пул потоков и дочерние процессы в Node.js. Libuv создает пул с четырьмя потоками (пул потоков), которые используются только в том случае, если асинхронный API недоступен.

Итак, как видите, Libuv делает возможной многопоточность из коробки. Но чтобы полностью понять рабочий процесс Node.js, позвольте мне рассказать вам больше о том, что происходит в фоновом режиме ваших приложений Node.js.

Что такое Node.js?

Node.js — это управляемая событиями среда выполнения JavaScript, основанная на движке Google V8 JavaScript, который также работает в фоновом режиме Google Chrome. V8 компилирует код JavaScript в машинный код, понятный компьютеру. Как мы теперь знаем, Libuv написан на C, а JavaScript-движок V8 в основном написан на C++ с небольшим количеством JavaScript.

Поскольку Node.js построен на базе движка V8, можно использовать JavaScript вне браузера. Это было невозможно до появления Node.js. Раньше JavaScript использовался только внутри браузера, чтобы сделать веб-сайты более динамичными. Другими словами, JavaScript был языком программирования только для внешнего интерфейса.

Цикл событий

Как мы знаем, Event Loop поставляется Libuv и является сердцем системной архитектуры Node.js. Поскольку цикл обработки событий выполняется после кода верхнего уровня, можно запустить приложение Node.js без цикла обработки событий, не используя никаких обратных вызовов, но в большинстве случаев это не так.

Этапы цикла событий

Цикл событий — это, как следует из самого термина, цикл событий, который обрабатывает обратные вызовы в JavaScript. Концепция проста. Существует четыре основных этапа, отвечающих за макрозадачи, и два второстепенных этапа, отвечающих за микрозадачи.

Макрозадачи

  1. Обратные вызовы таймеров с истекшим сроком действия (setTimeout, setInterval)
  2. Опрос ввода-вывода и его обратные вызовы (файловая система, HTTP-запросы)
  3. Немедленные обратные вызовы (setImmediate)
  4. Закрыть обратные вызовы (файлы, прослушиватели сервера, процессы)

Цикл событий перейдет с фазы 4 на фазу 1, если ваше приложение Node.js ожидает обратных вызовов или если вы прослушиваете HTTP-сервер.

Микрозадачи

Микрозадачи выполняются между каждой основной фазой цикла событий в следующем порядке:

  1. process.nextTick() (не рекомендуется использовать)
  2. Обещания

Как использовать многопоточность по назначению?

Существует три способа использования нескольких потоков в приложении Node.js.

  • Дочерние процессы (1 поток для каждого процесса)
  • Кластеризация
  • Рабочие потоки (предпочтительно) (один и тот же процесс, несколько потоков)

Хотите узнать больше об этом? Посмотрите отличное видео от Брайана Хьюза (бывшего инженера-программиста Microsoft), в котором рассказывается о Node.js и о том, почему он не такой однопоточный, как мы могли бы подумать.

Спасибо, что прочитали мою вторую статью на Medium. Я надеюсь, что смог помочь вам освежить ваши знания о Node.js. Следите за новостями.

Ваше здоровье!

Надеюсь, вам понравилось это читать. Если вы хотите поддержать меня как писателя, рассмотрите возможность подписки стать участником Medium. Всего 5 долларов в месяц, и вы получаете неограниченный доступ к Medium.

Хотите поддержать меня? Купи мне кофе.

Читать дальше





Создавайте компонуемые интерфейс и серверную часть

Не создавайте веб-монолиты. Используйте Bit для создания и компоновки несвязанных программных компонентов — в ваших любимых фреймворках, таких как React или Node. Создавайте масштабируемые и модульные приложения с мощными и приятными возможностями разработки.

Перенесите свою команду в Bit Cloud, чтобы совместно размещать и совместно работать над компонентами, а также значительно ускорить, масштабировать и стандартизировать разработку в команде. Начните с компонуемых интерфейсов, таких как Design System или Micro Frontends, или исследуйте компонуемый сервер. Попробуйте →

Узнать больше