Есть два основных компонента Node, которые делают Node таким, какой он есть. Этими компонентами являются движок V8 и библиотека Libuv. Движок V8 по сути является интерпретатором/компилятором. Он преобразует код, который вы пишете на Javascript, в машинный код, понятный вашему компьютеру. Библиотека Libuv — это библиотека с открытым исходным кодом, которая упрощает асинхронные операции ввода-вывода. Он также обеспечивает доступ к циклу обработки событий и пулу потоков.

Цикл событий отвечает за выполнение функций обратного вызова. Во многих местах он описывается как оркестратор, потому что он получает события/триггеры (т. е. разрешение обещания, сетевой запрос и т. д.) и выполняет обратный вызов, связанный с этим событием. Теперь вы можете спросить, при чем здесь пул потоков? Иногда выполняемые задачи слишком тяжелы для запуска цикла событий самостоятельно, т. е. криптографические операции, сжатие, поэтому в этих случаях цикл событий выгружает эти тяжелые задачи в пул потоков для выполнения. Цикл событий автоматически решает, какие задачи он считает слишком тяжелыми, поэтому разработчику действительно не нужно беспокоиться об этом. Но, конечно, вы можете утруждать себя, если очень хотите, это тоже нормально.

Причина, по которой цикл событий называется так, заключается в том, что он делает именно то, что подразумевает его название. Он перебирает определенные классы событий, чтобы определить приоритет выполнения обратных вызовов. Сначала он проверяет, есть ли какие-либо обратные вызовы в классе Timer для запуска? Под классом таймера я подразумеваю такие вещи, как setTimeout и другие подобные функции. Затем он проверяет, есть ли какие-либо обратные вызовы ввода-вывода для выполнения. После этого он проверяет выполнение обратных вызовов setImmediate. Обратные вызовы setImmediate — это обратные вызовы, которые вы собираетесь запускать сразу после завершения операции ввода-вывода. Наконец, цикл событий проверяет обратные вызовы закрытия, т. е. закрытие сервера, закрытие сетевого соединения и т. д.

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

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

  1. Не используйте синхронные версии функций внутри обратных вызовов.
  2. Не делайте сложных вычислений внутри обратных вызовов — цикл внутри цикла внутри цикла.
  3. Будьте осторожны с очень большими предметами. Требуется время, чтобы преобразовать или проанализировать большие объекты в JSON или из него.

Так что на данный момент это от меня, ребята. Я очень надеюсь, что вы узнали что-то новое из этого. Удачного кодирования.