Потоки

Node.js использует два типа потоков:
i) основной поток, обрабатываемый циклом событий.
ii) различные вспомогательные потоки в рабочем пуле.

Цикл событий
Это механизм, который принимает обратные вызовы (функции) и регистрирует их для выполнения в какой-то момент в будущем. Он работает в том же потоке, что и правильный код JavaScript. Всякий раз, когда операция JavaScript блокирует поток, цикл обработки событий также блокируется.

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

Цикл событий — это то, что позволяет Node.js выполнять неблокирующие операции ввода-вывода, несмотря на то, что JavaScript является однопоточным

Возможности цикла событий:

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

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

Затем setTimeout помещается в очередь, задача отправляется в операционную систему, и для задачи устанавливается таймер. Затем эта задача извлекается из стека.

Затем третий оператор журнала консоли помещается в стек вызовов и регистрируется на консоли, а задача извлекается из стека.

Когда таймер, установленный функцией setTimeout, истекает, обратный вызов отправляется в очередь событий. Цикл событий при обнаружении пустого стека вызовов берет задачу в начало очереди событий и отправляет ее в стек вызовов. Функция обратного вызова для функции setTimeout запускает инструкцию и регистрируется в консоли, а задача извлекается из стека.

Реализация цикла событий

Цикл событий состоит из 6 фаз.

  • таймеры: на этом этапе выполняются обратные вызовы, запланированные setTimeout() и setInterval().
  • ожидающие обратные вызовы выполняет обратные вызовы ввода-вывода, отложенные до следующей итерации цикла.
  • ожидание, подготовка используется только для внутреннего использования.
  • опрос: получение новых событий ввода-вывода; выполнять обратные вызовы, связанные с вводом-выводом (почти все, за исключением обратных вызовов закрытия, тех, которые запланированы таймерами, и setImmediate()); node будет блокироваться здесь, когда это уместно.
  • проверить: здесь вызывается setImmediate() обратных вызовов.
  • обратные вызовы закрытия: некоторые обратные вызовы закрытия, например. socket.on('close', ...).

Между каждым запуском цикла событий Node.js проверяет, ожидает ли он каких-либо асинхронных операций ввода-вывода или таймеров, и корректно завершает работу, если таковых нет.

Пул потоков Libuv

libuv — это специальный библиотечный модуль, используемый для выполнения асинхронных операций. Эта библиотека также используется вместе с обратной логикой Node для управления специальным пулом потоков, называемым пулом потоков libuv.

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