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. Концепция проста. Существует четыре основных этапа, отвечающих за макрозадачи, и два второстепенных этапа, отвечающих за микрозадачи.
Макрозадачи
- Обратные вызовы таймеров с истекшим сроком действия (setTimeout, setInterval)
- Опрос ввода-вывода и его обратные вызовы (файловая система, HTTP-запросы)
- Немедленные обратные вызовы (setImmediate)
- Закрыть обратные вызовы (файлы, прослушиватели сервера, процессы)
Цикл событий перейдет с фазы 4 на фазу 1, если ваше приложение Node.js ожидает обратных вызовов или если вы прослушиваете HTTP-сервер.
Микрозадачи
Микрозадачи выполняются между каждой основной фазой цикла событий в следующем порядке:
- process.nextTick() (не рекомендуется использовать)
- Обещания
Как использовать многопоточность по назначению?
Существует три способа использования нескольких потоков в приложении Node.js.
- Дочерние процессы (1 поток для каждого процесса)
- Кластеризация
- Рабочие потоки (предпочтительно) (один и тот же процесс, несколько потоков)
Хотите узнать больше об этом? Посмотрите отличное видео от Брайана Хьюза (бывшего инженера-программиста Microsoft), в котором рассказывается о Node.js и о том, почему он не такой однопоточный, как мы могли бы подумать.
Спасибо, что прочитали мою вторую статью на Medium. Я надеюсь, что смог помочь вам освежить ваши знания о Node.js. Следите за новостями.
Ваше здоровье!
Надеюсь, вам понравилось это читать. Если вы хотите поддержать меня как писателя, рассмотрите возможность подписки стать участником Medium. Всего 5 долларов в месяц, и вы получаете неограниченный доступ к Medium.
Хотите поддержать меня? Купи мне кофе.
Читать дальше
Создавайте компонуемые интерфейс и серверную часть
Не создавайте веб-монолиты. Используйте Bit для создания и компоновки несвязанных программных компонентов — в ваших любимых фреймворках, таких как React или Node. Создавайте масштабируемые и модульные приложения с мощными и приятными возможностями разработки.
Перенесите свою команду в Bit Cloud, чтобы совместно размещать и совместно работать над компонентами, а также значительно ускорить, масштабировать и стандартизировать разработку в команде. Начните с компонуемых интерфейсов, таких как Design System или Micro Frontends, или исследуйте компонуемый сервер. Попробуйте →