[] Вы не знаете узла

Node.js Программа перевода самородков
[] Вы не знаете узла

В этом году на конференции Forward.js (саммите по JavaScript) я выступил с докладом под названием «Узел, которого вы не знаете», в котором я задал живой аудитории ряд вопросов о проблеме среды выполнения Node.js, однако большинствозаниматься технологиямиЗрители не смогли ответить на все из них.

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

Этот вопрос заставил меня высказаться, и я не думаю, что то, как мы обучаем Node, правильно. Большинство учебников по Nodejs посвящены местам за пределами пакетов Node и среды выполнения Node, большинство из которых инкапсулируют модули в среде выполнения Node (например,httpилиstream), проблема может быть скрыта в среде выполнения, но если вы не знаете среду выполнения Node, у вас проблемы.

Проблема: Большая часть содержания учебника по Nodejs сосредоточена на других местах, помимо пакетов Node и среды выполнения Node.

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

Если вы найдете неверный или вводящий в заблуждение ответ, пожалуйста, свяжитесь со мной.

Вопрос №1: Что такое стек вызовов? Это часть V8?

Стек вызовов на 100 % является частью V8, и это структура данных, которую V8 использует для отслеживания вызовов методов. Каждый раз, когда мы вызываем метод, V8 помещает ссылку на этот метод в стек вызовов, и V8 делает то же самое для каждого вложенного вызова любого другого метода, включая те, которые вызывают себя рекурсивно.

Screenshot captured from my Pluralsight course — Advanced Node.js
Скриншот из моего курса Pluralsight — Advanced Node.js

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

Почему это так важно для понимания Node? Потому что у вас есть только один стек вызовов на процесс Node. Если вы держите стек вызовов занятым, весь ваш процесс Node тоже будет занят. Имейте это в виду!

Вопрос № 2: Что такое цикл событий? Это часть V8?

Как вы думаете, где на этой диаграмме находится цикл событий?

Screenshot captured from my Pluralsight course — Advanced Node.js
Скриншот из моего курса Pluralsight — Advanced Node.js

ответlibuv. Цикл событий не является частью V8!

Цикл событий — это объект, который манипулирует внешними событиями и превращает их в вызовы обратного вызова.Это цикл, который берет события из очереди событий и помещает функцию обратного вызова события в стек вызовов. И процесс цикла делится на несколько независимых этапов.

Если вы впервые слышите о цикле событий, эти концепции, вероятно, не очень вам помогут. Цикл событий является частью более крупной схемы:

Screenshot captured from my Pluralsight course — Advanced Node.js
Скриншот из моего курса Pluralsight — Advanced Node.js

Вам нужно понять этот план, прежде чем вы поймете цикл событий, вам нужно понять роль V8 здесь, понять API-интерфейсы Node и узнать, как события ставятся в очередь и обрабатываются V8.

API-интерфейсы узлов похожи наsetTimeoutилиfs.readFileНекоторые методы не являются частью самого JavaScript, это методы, предоставляемые Node.

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

Вопрос № 3: Что делает Node, когда стек вызовов и очередь цикла событий пусты?

Узел просто выйдет.

Когда вы выполняете программу Node, Node автоматически запускает цикл обработки событий, а когда нет обработки событий и других задач, Node выходит из процесса.

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

Вопрос № 4: Помимо V8 и Libuv, какие внешние зависимости есть у Node?

Ниже перечислены все внешние библиотеки, которые может использовать процесс Node:

  • http-parser
  • c-ares
  • OpenSSL
  • zlib

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

Вы хотите запомнить их, потому что хотите знать, где выполняется ваша программа. Если вы выполняете какую-то работу по сжатию данных, могут возникнуть проблемы с библиотекой zlib. Node невиновен.

Вопрос № 5: Можно ли запустить процесс Node без V8?

Это может быть сложный вопрос. Вам определенно нужна виртуальная машина для выполнения процессов Node, но V8 — не единственная виртуальная машина, вы также можете использовать Chakra.

Проверьте этот репозиторий Github, чтобы отслеживать ход проекта node-chakra:

Вопрос № 6: В чем разница между module.exports и экспортом?

ты можешь использоватьmodule.exportsЧтобы экспортировать API модуля, вы также можете использоватьexports, но есть один нюанс:

module.exports.g = ...  // Ok

exports.g = ...         // Ok

module.exports = ...    // Ok

exports = ...           // Not Ok

Зачем?

exportsпросто параmodule.exportsссылка или псевдоним при измененииexportsкогда вы непреднамеренно пытаетесь изменитьmodule.exports, Но изменить официальный API (т.е.module.exports) не имеет никакого эффекта, вы просто получите локальную переменную в объеме модуля.

Вопрос № 7: Почему переменные верхнего уровня не являются глобальными переменными?

если тыmodule1определяет переменную верхнего уровняg:

// module1.js

var g = 42;

и выmodule2полагатьсяmodule1и пытаюсь получить доступ к этой переменнойg, вы получите ошибкуg is not defined.

Зачем?Если вы сделаете то же самое в браузере, вы сможете получить доступ к переменным верхнего уровня во всех скриптах.

Каждый Node-файл имеет собственное IIFE (немедленно вызываемое функциональное выражение) за кулисами, и все переменные, объявленные в Node-файле, ограничены рамками этого IIFE.

Похожие вопросы: В файле Node есть только следующая строка кода, что будет результатом ее выполнения:

// script.js</pre>

console.log(arguments);

Вы увидите некоторые параметры!

Зачем?

Поскольку Node выполняет функцию. Node оборачивает ваш код в функцию, которая явно определяет те 5 параметров, которые вы видели выше.

Вопрос №8:exports,requiremoduleЭти три объекта глобально доступны в каждом файле, но они разные в каждом файле, почему?

когда вам нужно использоватьrequireобъект, вы просто используете его напрямую как глобальную переменную, однако, если вы сравните 2 разных файлаrequireРазница между объектами, вы найдете 2 разных объекта, что происходит?

Опять же по той же причине IIFE (немедленно вызываемое функциональное выражение):

Как видите, IIFF передает в ваш код следующие 5 параметров:exports, require, module, __filename, and __dirname.

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

Вопрос № 9: Что такое циклические зависимости в Node?

если у тебя естьmodule1зависит отmodule2module2в свою очередь зависит отmodule1, что случится? ошибка?

// module1

require('./module2');

// module2

require('./module1');

Будьте уверены, об ошибках не будет сообщено, Node это позволяет.

так,module1зависит отmodule2, но потому чтоmodule2зависит отmodule1,Тем не мениеmodule1Еще не готов,module1получит толькоmodule2неполная версия.

Система выдала предупреждение.

Вопрос № 10: Когда уместно использовать файловую системуСинхронизироватьметод (например, readFileSync)?

в каждом узлеfsвсе методы имеют синхронную версию, почему вы хотите использовать синхронный метод вместо асинхронного?

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

Однако, если вы используете синхронный метод в обратном вызове по запросу, как HTTP-сервер, это действительно 100% неправильно! Не делай этого.

Я надеюсь, что вы сможете ответить на некоторые или все вопросы, вот написанные мной статьи, в которых подробно рассказывается о Node.js:


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,React,внешний интерфейс,задняя часть,продукт,дизайнЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.