Оглавление
Глава 3. Создаем Ваше первое приложение
3.1.3 Сохранение и загрузка в REPL
3.1.8 Асинхронные операции в REPL
Глава 3. Создаем Ваше первое приложение
Даже самый длинный путь начинается с первого шага.
-Конфуций
К этому момент, у Вас уже установлена платформа Node.js в Вашу систему. Для запуска примеров из этой главы, Вы должны использовать командную строку Вашей ОС. И нет особой разницы, в какой ОС Вы работаете – Linix, Windows или macOS. Все примеры работают одинаково вне зависимости от используемой системы. Использовать платформу Node.js можно двумя способами. Для простых примеров можно использовать интерактивную оболочку. Второй способ запуска приложения заключается в передаче имени исходного файла команде node. В последнем случае не требуется больше никакого взаимодействия с пользователем.
3.1 Интерактивный режим
Вы можете войти в интерактивный режим Node.js, введя команду node в командной строке, как Вы можете увидеть в листинге 3.1
# node >
Листинг 3.1 Интерактивный режим Node.js
В интерактивном режиме Вы можете напрямую ввести код JavaScript в командной строке и выполнить его. Этот тип пользовательского интерфейса называется – REPL – read – eval – print loop(цикл чтения – оценки – печати), что означает что команды считываются в командной строке и оцениваются, а затем уже результат выводится в командной строке. Этот режим не предназначен для реализации и запуска полноценных приложений. Вместо этого, данный интерфейс в основном применяют для запуска и тестирования отдельных участков кода. На рисунке 3.1 показано, как работает интерактивный режим.
3.1.1 Использование Node.js
В листинге 3.2 показано, как выполнять команды в Node.js REPL.
# node > console.log('Hello World!'); Hello world! undefined >
Листинг 3.2 Выполнение команд в Node.js REPL
Команды JavaScript заканчиваются знаком “;” в Node.js REPL. Символ разрыва строки(нажатие Enter) завершает ввод текущей команды и отправляет ее движку JavaScript. В этом примере метод console.log
с аргументом “Hello World!
” оценивается движком и результат Hello World! выводится в командную строку. Как видно из листинга 3.2, помимо вывода Hello world!, также и вывелось слово undefined. Это происходит потому что значение функции console.log
– возвращаемое. В нашем случае оно будет – undefined, так как мы его не определили. Помимо команд вывода, в REPL Вы можете также выполнять все JavaScript команды в Node.js, как показано в Листинге 3.3.
> function greet(name) { ... console.log(`Hello ${name}`); ... }; greet('world'); Hello world undefined >
Листинг 3.3 Определение простой Node.js REPL функции
В листинге 3.3 показано определение функции в REPL Node.js, которая принимает имя как параметр и которая выводит в консоль результат ее выполнения. После ее определения вызывается функция greet
с параметром world
. Вывод содержит фразу Hello world и уже знакомое нам ключевое слово – undefined. Если Вы хотите запускать разные команды в Node.js REPL, которые зависят друг от друга, Вы можете с легкостью выполнять их, так как контекст запоминается в течение всего сеанса. Например, если Вы определите функции или выполните присвоение переменным, они будут сохранены в контексте даже после перехода в консоли на новую строку. В Листинге 3.4 Вы можете видеть, как это работает на конкретном примере:
$ node > const sayHello = 'Hello world!'; undefined > console.log(sayHello); Hello world! undefined >
Листинг 3.4 Выполнение взаимозависимых команд
В примере из листинга 3.4, мы инициализируем значение константы sayHello
. Эта константа используется в выводе в следующей строке кода. Среди наиболее важных возможностей REPL Node.js – автозаполнение функций. Если Вы нажмете клавишу Tab, ничего больше не вводя, Вы получите список всех доступных объектов. Если Вы используете автозаполнение в сочетании с одной или несколькими буквами, отобразятся только подходящие предложения. Еще одна особенность, как можно увидеть в Листинге 3.3 – это многострочные команды – когда код вводится не в одну строку, а в несколько. Незавершенная команда обознается многоточием, вместо знака больше >
в командной строке. Многострочные команды могут быть достигнуты, например при вводе незавершенных блоков кода или оператора plus для конкатенации или вычисления строк в конце строки.
3.1.2 Другие REPL команды
Одной из ключевых возможностей REPL Node.js является то, что он представляет несколько команд для управления REPL в дополнение к командам JavaScript. Команды всегда начинаются с символа точки и не всегда заканчивается знаком “;“. Таблица 3.1 содержит список этих команд.
Команда | Описание |
.break | Завершает текущий вывод. Команда .break особенно полезна для многострочных команд |
.clear | Псевдоним для .break |
.exit | Завершает REPL Node.js |
.help | Выводит список доступных команд |
.load<file> | Загружает сохраненную сессию из файла в текущую REPL |
.save<file> | Сохраняет команды текущей сессии REPL в файл |
.editor | Открывает режим редактора, где Вы можете определить блок кода. Ctrl+D выполняет блок, и Ctrl+C служит для выхода из режима редактора без выполнения кода |
Таблица 3.1 Доступные REPL команды
Существует два способа выхода из REPL: с помощью команды .exit
или нажав на комбинацию Ctrl+D. Или два раза нажав комбинацию Ctrl +C.
Команды .break
и .clear
используют, когда командная строка заблокирована некорректным вводом. Листинг 3.5 показывает как использовать эти команды.
> function greet(name) { ... .break >
Листинг 3.5 Использование команды .break
В примере из Листинга 3.5, мы начинаем вводить функцию с именем greet
. Но вдруг мы перехотели ее вводить и решили прекратить ввод. Мы не можем просто нажать на клавишу Enter, так как это введет только символ перевода каретки на новую строку и ввод функции продолжится. Если Вы видите, что допустили ошибку, Вы можете ввести команду .break
и снова попытаться напечатать функцию. Такого же эффекта можно добиться нажатием на комбинацию клавиш Ctrl+C. Node.js REPL также предоставляет функционал по отображению истории последних введенных команд. Благодаря этой возможности, Вам не нужно заново вводить команду, Вы можете использовать клавиши Up и Down для навигации по истории введённых команд. Так что Вы можете найти команду с ошибками, исправить ее и отправить движку Node.js.
3.1.3 Сохранение и загрузка в REPL
Если Вы хотите запустить более сложные комплексные тесты в REPL, или сохранить результаты, Вы можете использовать команды .save
и .load
для сохранения ранее выполненных команд или для загрузки файла с командами/кодом JavaScript в текущую оболочку REPL.
Листинг 3.6 демонстрирует, как Вы можете использовать команды .load
и .save
. Для того, чтобы посмотреть, как Вы можете их использовать, Вам необходимо сначала ввести команду console.log
. И уже после мы сохраняем текущую сессию в файл myShell.js. Теперь этот файл содержит командную строку в том виде, в котором Вы ее ввели, но не содержит вывод этой команды. Затем мы обратно загружаем нашу команду в текущий сеанс, выполнив инструкцию .load
. Каждая команда читается из файла построчно, выполняется и отображается в текущий вывод – консоль. Вы также можете использовать команду .load
для подготовки к программному эксперименту. Для этого Вы можете заранее подготовить в файле набор команд, которые Вам понадобятся в ходе работы с REPL.
> console.log('Hello World!'); Hello world! undefined > .save myShell.js Session saved to:myShell.js > .load myShell.js > console.log('Hello World!'); Hello world! undefined >
Листинг 3.6 Использование команд .load и .save
3.1.4 Контекст REPL
Как и в языке JavaScript, Node.js REPL предоставляет глобальный контекст, к которому Вы можете получить доступ из любой части программы. В REPL некоторые переменные уже зарегистрированы в глобальном контексте, что облегчает Вам работу как разработчику. Таким образом Вам доступны все модули Node.js, без необходимости загружать их по отдельности через систему модулей. Например, Вы можете использовать http.STATUS_CODES
для отображения списка предопределенных HTTP кодов статусов. Помимо этих модулей, Вы также можете загружать файлы через Node менеджер пакетов(npm) через систему модулей или используя функцию require
. В глобальной области видимости Node.js REPL переменная _ дает вам еще одну преимущество: эта переменная всегда содержит значение последней команды. Например если последняя команда, которую Вы введете будет 1+1, переменная _ будет содержать значение 2. Если Вы вызываете например, метод process.uptime()
, _ содержит возвращаемое значение этого метода.
3.1.5 История REPL
В Node.js существует несколько специальных переменных среды. Две из них касаются истории записей. Вероятнее всего Вы уже знаете эту функцию из командной строки Вашей ОС. В случае Unix систем – это Bash, файл называемый .bash_history
, где хранится история всех введённых команд. Аналогичная функциональность доступна в Node.js REPL. В конфигурации по умолчанию, история введённых команд сохраняется в файле
.node_repl_history
в главной директории пользователя. Вы можете использовать две переменные среды из Вашей ОС для управления историей. Переменную NODE_REPL_HISTORY
Вы можететакже использовать для изменения местоположения истории. Если эта переменная не установлена, используется значение по умолчанию. Вторая переменная среды, NODE_REPL_HISTORY_SIZE
, определяет сколько строк команд может содержать файл истории, после чего они будут затерты более новыми командами. Значение по умолчанию – 1000.
3.1.6 Режим запуска REPL
Также Вы можете переменную среды NODE_REPL_MODE для определения режима запуска Node.js REPL. Ниже представлены 3 доступных значения переменной:
- sloppy –REPL установлен в нестрогий режим. Переопределяются правила строгого режима JavaScript. Это режим для запуска REPL по умолчанию
- strict – Значение
strict
активирует строгий режим. В этом случае, например, больше нельзя создавать в объекте несколько свойств с одинаковым именем, а попытка изменить константу вызовет ошибку. Очень хорошее и подробное описание строгого режима можно найти по адресу https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. - magic – Это значение в данный момент признано устаревшим и используется как псевдоним значения
sloppy
Вы также можете запустить Node.js напрямую в строгом режиме при запуске с командной опцией --use_strict
. В большинстве случаев, это имеет смысл, так как Вы можете безопасно использовать спецификации use strict
и строгий режим запрещает многие анти паттерны в JavaScript.
Используя Node.js REPL в качестве инструмента, Вы можете легко протестировать исходный код, чтобы в интерактивном режиме посмотреть как платформа Node.js ведет себя в различных ситуациях. Node.js REPL не подходит для больших приложений, в этом случае используется другой способ запуска Node.js.
3.1.7 Поиск в REPL
Node.js REPL предоставляет не только возможность ручного поиска в списке команд, используя клавиши Up и Down, но и выполнять поиск в истории команд. Используя комбинации клавиш Ctrl+R и Ctrl+S Вы можете перемещать вперед и назад по поисковым запросам.
Вы получаете доступ к этой функции в основном когда хотите выполнить снова введенную ранее строку, но не хотите ее вводить второй раз. Поиск ищет искомый код, независимо от того, находится он в начале или в конце файла. Найденное совпадение отображается в командной строке и Вы можете изменить код перед тем как снова отправить его интерпретатору Node.js. Если искомый текст встречается несколько раз, Вы можете перейти к следующему совпадению, снова нажав на сответстсвующий ярлык или перейти к предыдущему совпадению, если искомый вариант не удовлетворил Вашему поиску.
3.1.8 Асинхронные операции в REPL
JavaScript предоставляет различные средства реализации асинхронных операций, такие как обратные вызовы или промисы. Несколько лет назад была реализована концепция async-await
, которая далее будет обсуждаться в этой книге. Вы можете использовать ключевое слово await
для ожидания выполнения асинхронных операций без регистрации функций обратного вызова. Движок приостанавливает выполнение текущего блока кода до тех пор, пока не будет доступен результат. Остальная часть приложения остается рабочей и может продолжать работу.
Обычно Вы должны указать ключевое слово async
при декларации асинхронной функции. Последние версии стандарта ECMAScript предоставляют возможность, которая называется top-level await, которая позволяет Вам использовать await
даже на верхнем уровне Вашего приложения и без использования указания функции как async
. Эта возможность также доступна в Node.js REPL начиная с версии 16.6, и также она включена по умолчанию и больше нет необходимости использовать флаг --experimental-repl-await.
Листинг 3.7 показывает пример объекта promise
, созданного Promise.resolve
, для того чтобы показать как можно использовать ключевое слово await
. Promise.resolve
– Это один из самых простых способов имитации асинхронной операции путем создания promise
объекта и его немедленного решения .
node Welcome to Node.js v18.14.0. Type ".help" for more information. > await Promise.resolve('Hello world'); 'Hello world'
Листинг 3.7 Использование top-level await в REPL