Подтвердить что ты не робот

Node.js понимание цикла событий (с диаграммой)

Я читал этот и этот, смотрел this...

Я составил схему того, как я ее понимаю:

введите описание изображения здесь

  • Обратные вызовы (функции) Javascript могут присутствовать в current queue, check queue, close callbacks queue, timers queue и I/O callbacks queue.
  • Js-код запускается только из current queue одной функции (задачи/задания) за раз.
  • Js-код, выполняемый в настоящий момент, может добавить микротаски (задания) к current queue, которые будут выполняться после себя и макрозадачи (задачи), в check queue. Он может добавлять задачи в другие очереди только не так, попросив API сделать это. Фаза
  • Idle, prepare используется для некоторого внутреннего бизнеса node js (может быть, как сборка мусора).
  • Poll фазовый опрос потоков из пула потоков и заполняет очереди соответствующими обратными вызовами. Фазы
  • Idle, prepare и Poll не имеют очередей для связанных с ними js-обратных вызовов.
  • (четыре) Темы в thread pool идентичны и не имеют специализации.
  • Цикл событий принимает и выполняет задачи один за другим из каждой очереди до тех пор, пока не будет пуст, а затем перейдет к следующей очереди.
  • Задачи в очередях не имеют связанных с ними заданий (микросервисов). Задания создаются только во время выполнения задачи или другого задания и присутствуют только в current task queue.

Является ли это понимание правильным или я что-то упускаю?

Файл MS Power Point.pptx с диаграммой можно найти здесь.

4b9b3361

Ответ 1

Диаграмма кажется довольно сложной. Я нахожу, что аналог короля совершенно совершенен в этом контексте, чтобы понять уровень серого на уровне цикла событий.

Представьте, что код, который вы хотите запустить, является королем, а node - это армия слуги.

День начинается с одного слуги, просыпающего короля и спрашивающего его, нуждается в чем угодно. Царь дает слуге список задач и идет вернемся спать немного дольше. Слуга теперь распределяет эти задачи среди его коллег, и они приходят на работу.

Как только слуга заканчивает задачу, он выходит за пределы квартала королей сообщить. Король одновременно дает одному слуге и слушает о чем он сообщает. Иногда король дает слуге больше задач на выходе.

Жизнь хороша, потому что царские слуги выполняют все свои задачи в параллельно, но только сообщать с одним результатом за раз, поэтому король может фокус.

Король здесь является основным node процессом. Это то, как nodejs называется однопоточным, но асинхронным.

Ответ 2

Всякий раз, когда мы запускаем программу узла, узел автоматически создает один поток, а затем выполняет весь наш код. Внутри одного потока есть нечто, называемое циклом обработки событий. Вы можете думать о цикле событий как о управляющей структуре, которая решает, что должен делать наш единственный поток в любой данный момент времени. Этот цикл событий является абсолютным ядром каждой программы, которую мы запускаем, и каждая программа, которую мы запускаем, имеет в точности один цикл событий.

После выполнения первой строки кода мы входим в цикл обработки событий. Этот цикл событий похож на цикл WHILE. так что этот цикл обработки событий или цикл while будут выполняться снова и снова. Поэтому каждый раз, когда цикл событий запускается внутри нашего приложения узла, мы называем это одним тиком. Все тело выполняется в один тик.

Тик цикла событий: что происходит во время каждого тика?

1-Итак, самое первое, что происходит, это то, что узел просматривает все различные функции, которые были переданы, чтобы установить тайм-аут и установить интервал. Если какой-либо из этих таймеров истек, узел вызывает соответствующие обратные вызовы, связанные с каждым из них.

2 - для второго шага узел просматривает ожидающие задачи ОС и ожидающие операции и вызывает соответствующие обратные вызовы. Таким образом, во втором шаге примечание рассмотрит эту коллекцию всех различных задач и операций, и если какая-либо из этих вещей была выполнена или какие-либо новые события были инициированы, узел выполняет соответствующие обратные вызовы.

3-На этом шаге узел фактически временно приостанавливает выполнение. Таким образом, узел просто сидит здесь, он делает паузу и говорит, что "я продолжу, когда произойдет какое-то количество событий". Таким образом, во время этой фазы паузы узел решает, что он не будет просто проходить через цикл обработки событий настолько быстро, насколько это возможно. Цикл while будет выполняться так быстро, как только возможно, но на самом деле это не то, что происходит внутри цикла событий внутри цикла событий. Эта пауза во время шага 3 просто сидит и говорит, что вы знаете, что у меня нет никакой другой работы. Я просто подожду, пока не увижу, что новое незавершенное задание выполнено.

4-узел снова смотрит на ожидающие таймеры на шаге 1. Но в этом случае узел не заботится об установлении времени ожидания и установлении интервальных вызовов функций. Он ищет только те функции, которые были зарегистрированы с помощью setImmediate()

5-Он обрабатывает любые близкие события. По сути, этот последний шаг в цикле событий - это просто обработка кода очистки и очистка после себя.

К каждому циклу while() должно быть привязано какое-то условие. Мы помещаем это условие в круглые скобки while (условие) и всякий раз, когда это условие возвращает false, цикл while больше не собирается выполняться. та же идея применима и к циклу событий. Таким образом, каждый раз, когда цикл событий собирается выполняться, узел сначала выполняет быструю проверку, чтобы решить, должен ли он позволить циклу перейти на другую итерацию. если узел решит, что цикл не должен быть введен снова, тогда весь цикл обработки событий пропускается. Узел выполняет три отдельные проверки, чтобы решить, следует ли продолжать цикл обработки событий для другой итерации.

Сначала проверьте, есть ли еще какие-либо функции, которые были зарегистрированы с установленным таймаутом, установленным интервалом или установлены немедленно и все еще должны быть выполнены.

Во-вторых, посмотреть, есть ли какие-либо ожидающие выполнения задачи операционной системы. Пример задачи операционной системы - это что-то вроде HTTP-сервера, прослушивающего запросы на каком-либо порту.

В-третьих, если есть какие-либо длительные операции, которые все еще выполняются внутри нашей программы. Примером длительной операции может быть что-то вроде вызова функции внутри модуля FS для считывания некоторого файла с жесткого диска.

Модуль libuv отвечает за некоторые конкретные функции в стандартной библиотеке. для НЕКОТОРЫХ вызовов стандартных функций библиотеки сторона C++ и libuv решают делать дорогостоящие вычисления вне цикла событий. Они создают нечто, называемое пул потоков, этот пул потоков представляет собой серию из четырех потоков, которые можно использовать для вычислительной работы. интенсивные задачи, такие как функции хеширования.

По умолчанию libuv создает четыре потока в этом пуле потоков. Таким образом, это означает, что в дополнение к этому потоку, используемому для цикла событий, есть четыре других потока, которые можно использовать для разгрузки дорогих вычислений, которые должны выполняться внутри нашего приложения. Многие функции, включенные в стандартную библиотеку узлов, автоматически используют этот пул потоков.

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