Что такое петля событий? 😎
Цикл событий - это то, что позволяет Node. js выполнять неблокирующие операции ввода-вывода - несмотря на то, что JavaScript является однопоточным - путем передачи операций ядру системы. всякий раз, когда это возможно. Цикл событий - один из наиболее важных аспектов работы Node.js.
Почему это так важно? 🤷♂️
Потому что он объясняет, как Node.js может быть асинхронным и иметь неблокирующий ввод-вывод. Код JavaScript Node.js выполняется в одном потоке. Одновременно происходит только одно событие. Node.js активно использует события, и это также одна из причин, по которой Node.js работает довольно быстро по сравнению с другими подобными технологиями. Как только Node запускает свой сервер, он просто инициирует свои переменные, объявляет функции, а затем просто ждет, когда произойдет событие.
Пойдем в цикл событий !! 🕵️♂️
Стек вызовов:
Самая первая простая структура данных. Каждый раз, когда мы вызываем функцию, она помещается в стек, и каждый раз, когда мы возвращаемся из функции, она выскакивает из стека. Именно здесь весь ваш код javascript выталкивается и выполняется один за другим, когда интерпретатор читает вашу программу и выскакивает после завершения выполнения.
Очередь событий узла:
Иногда ее называют очередью сообщений или очередью обратного вызова. Цикл событий отправляет обратные вызовы из очереди событий в стек вызовов. Цикл событий выполняет задачи из очереди событий только тогда, когда стек вызовов пуст.
Это то место, куда ваш асинхронный код отправляется и ожидает выполнения.
Цикл событий:
Затем идет цикл событий, который продолжает работать непрерывно и проверяет основной стек, если у него есть какие-либо кадры для выполнения, если нет, то он проверяет очередь обратного вызова, если в очереди обратного вызова есть коды для выполнения, он выталкивает сообщение из нее в основной стек. для казни.
Давайте проясним цикл событий на примере:
Рассмотрим следующий код: 💻
Если вы запустите предыдущий код, вы получите результат, подобный следующему:
i am first
i am third
i am second
Причина очевидна: setTimeout()
ждет пять секунд и распечатывает результат; однако это не блокирует цикл событий.
Давайте установим таймер на 0
секунды и посмотрим, что произойдет:
Результат все тот же:
i am first
i am third
i am second
Почему так? Даже если вы установите таймер на 0
, он попадет в очередь; однако он немедленно обрабатывается, так как его время составляет 0
секунд. Цикл событий распознает, что стек все еще не пуст, то есть третья консоль находилась в процессе; поэтому он подталкивает обратный вызов после следующего тика цикла событий.
Когда вызывается setTimeout (), браузер или Node.js запускает таймер. По истечении таймера, в данном случае сразу после того, как мы установили 0 в качестве тайм-аута, функция обратного вызова помещается в очередь сообщений.
Цикл отдает приоритет стеку вызовов, и сначала он обрабатывает все, что находит в стеке вызовов, а когда там ничего нет, он переходит к подбору вещей из очереди сообщений.
Нам не нужно ждать, пока такие функции, как setTimeout
, fetch или другие, выполнят свою работу, потому что они предоставляются браузером и живут в своих собственных потоках. Например, если вы установите тайм-аут setTimeout
на 2 секунды, вам не нужно ждать 2 секунды - ожидание происходит где-то еще.
Многопоточность против однопоточной? 🙄
Многопоточный подход обеспечивает параллелизм с использованием потоков, так что несколько программ могут выполняться одновременно. С преимуществами приходят и проблемы; в многопоточной системе действительно сложно справиться с параллелизмом и взаимоблокировкой.
С другой стороны, при однопоточности нет шансов зайти в тупик в процессе, и управлять кодом также легко. Вы все еще можете взломать и использовать цикл событий без причины; однако дело не в этом.
Node.js использует однопоточную среду выполнения; однако внутри он создает несколько потоков для различных операций ввода-вывода. Это не означает, что он создает потоки для каждого соединения, libuv содержит системные вызовы интерфейса переносимой операционной системы (POSIX) для некоторых операций ввода-вывода.
Если однопоточные программы работают правильно, они никогда не будут блокировать ввод-вывод и всегда будут готовы принять новые соединения и обработать их.
Является ли Node.js однопоточным?
- Да! И ты прав. 🤨
- Нет! И Вы снова правы. 🤔
На самом деле, в Node.js есть V8, и код выполняется в основном потоке, где выполняется цикл обработки событий (поэтому мы говорим, что он однопоточный).
Но, как мы знаем, Node.js - это не просто V8. Существует множество API (C ++), и все это управляется Event Loop, реализованным через libuv (C ++).
C ++ работает в основе кода JavaScript и имеет доступ к потокам. Если вы запустите синхронный метод JavaScript, который был вызван из Node.js, он всегда будет выполняться в основном потоке. Но если вы запустите какую-то асинхронную вещь, она не всегда будет выполняться в основном потоке: в зависимости от того, какой метод вы используете, цикл событий может направить его в один из API, и он может быть обработан в другой поток.
Так является ли Node.js многопоточным?
Поэтому, когда люди спрашивают вас, является ли Node многопоточным или однопоточным, вы должны задать дополнительный вопрос: «Когда?».
Если вы зашли так далеко, прочитав всю статью, поздравляем 😃 Вы молодец.
❤ Спасибо, что прочитали, и если этот пост был полезен, нажмите Clapp! И не забудьте почитать другие мои статьи.