Это продолжение ответов на вопросы, размещенные в известном репо Node Beyond Basics, спасибо автору за создание такого блестящего ресурса по Node. Для просмотра предыдущих частей перейдите по следующим ссылкам:
19. Когда можно использовать методы файловой системы *Sync
?
Методы *Sync
представляют собой синхронную блокирующую версию функций spawn
, exec
и execFile
из модуля child_process
, которая будет ожидать завершения дочернего процесса.
const { spawnSync, execSync, execFileSync } = require(“child_process”);
Эти синхронные версии потенциально полезны при попытке упростить задачи сценариев или любые задачи обработки при запуске, но в противном случае их следует избегать.
20. Почему переменные верхнего уровня не являются глобальными?
Переменные верхнего уровня не являются глобальными из-за метода require()
, так как всякий раз, когда нам требуется файл в другом файле, require
будет обертывать наш код, который при необходимости предоставит частную область для каждого файла.
21. Объекты exports
, require
и module
глобально доступны в каждом модуле, но в каждом модуле они разные. Как?
Перед компиляцией модуля Node оборачивает код модуля в функцию, которую мы можем проверить с помощью свойства оболочки модуля.
~ $ node > require (‘module’).wrapper > [ ‘(function (exports, require, module, __filename, __dirname}) { ‘, > ‘\n});’ >
Node не выполняет код, который вы пишете в файле напрямую. Он выполняет эту функцию-оболочку, в теле которой будет ваш код. Это то, что удерживает переменные верхнего уровня, определенные в любом модуле, в пределах этого модуля.
22. Если вы запустите файл JavaScript с единственной строкой: console.log(arguments);
with Node, что именно Node напечатает?
Если мы запустим файл JavaScript, просто распечатав в нем аргументы, он напечатает следующий фрагмент:
{ ‘0’: {}, ‘1’: [Function: require] { resolve: [Function: resolve] { paths: [Function: paths] }, main: Module { id: ‘.’, path: ‘/Users/navitas28/Work/Learning/Node’, exports: {}, filename: ‘/Users/navitas28/Work/Learning/Node/args.js’, loaded: false, children: [], paths: [Array] }, extensions: [Object: null prototype] { ‘.js’: [Function (anonymous)], ‘.json’: [Function (anonymous)], ‘.node’: [Function (anonymous)] }, cache: [Object: null prototype] { ‘/Users/navitas28/Work/Learning/Node/args.js’: [Module] } }, ‘2’: Module { id: ‘.’, path: ‘/Users/navitas28/Work/Learning/Node’, exports: {}, filename: ‘/Users/navitas28/Work/Learning/Node/args.js’, loaded: false, children: [], paths: [ ‘/Users/navitas28/Work/Learning/Node/node_modules’, ‘/Users/navitas28/Work/Learning/node_modules’, ‘/Users/navitas28/Work/node_modules’, ‘/Users/navitas28/node_modules’, ‘/Users/node_modules’, ‘/node_modules’ ] }, ‘3’: ‘/Users/navitas28/Work/Learning/Node/args.js’, ‘4’: ‘/Users/navitas28/Work/Learning/Node’ }
Первый аргумент — это объект exports
, который начинается пустым. Затем у нас есть объекты require/module
, оба из которых являются экземплярами, связанными с исполняемым нами файлом args.js. Это не глобальные переменные. Последние два аргумента — это путь к файлу и путь к его каталогу.
23. Как модуль может быть одновременно «требуемым» для других модулей и исполняемым непосредственно с помощью команды node?
Это достижимо благодаря свойству main
объекта require
. Свойство main используется, чтобы различать, выполняется ли сценарий напрямую или требуется. Мы можем легко различить оба случая, как показано ниже.
if (require.main === module) { // the script is being executed directly here. } else { // the script is being required. }
24. Какой пример встроенного потока в Node, который доступен как для чтения, так и для записи?
zlib.createGzip
— это поток преобразования, доступный как для чтения, так и для записи. По сути, это дуплексный поток, который можно использовать для изменения или преобразования данных по мере их записи и чтения.