Чем на самом деле является Node.js?

Node.js это — среда выполнения JavaScript. Что же это значит, и как работает?
Окружение Node.js включает все, что вам нужно для выполнения программы, написанной на JavaScript.
Раньше вы могли запустить JavaScript только в браузере, но однажды разработчики расширили его, и теперь вы можете запускать JS на своем компьютере в качестве отдельного приложения. Так появился Node.js.
Теперь вы можете сделать гораздо больше с JavaScript, чем просто интерактивные веб-сайты.
Теперь у JavaScript есть возможность делать то, что могут делать другие скриптовые языки программирования, такие как Python.
Оба — браузерный JavaScript и Node.js запускаются в среде выполнения V8. Этот движок использует ваш JS код, и преобразует его в более быстрый машинный код. Машинный – низкоуровневый код, который компьютер может запускать без необходимости сначала его интерпретировать.
Почему Node.js?
Вот формальное определение, данное на официальном сайте Node.js:
— Node.js — среда выполнения JavaScript, основанная на JavaScript движке V8 из Chrome.
— Node.js использует управляемую событиями, неблокирующую модель ввода-вывода, которая делает ее легкой и эффективной.
— Пакетная экосистема Node.js, npm, является самой большой экосистемой библиотек с открытым исходным кодом в мире.
Мы уже обсуждали первую строку этого определения: «Node.js — среда выполнения JavaScript, основанная на JavaScript движке V8 из Chrome». Теперь давайте разбираться в двух других строках, так мы сможем понять, почему Node.js так популярен.
I/O означает ввод/вывод. Это может быть что угодно: от чтения/записи локальных файлов до HTTP-запроса в API. I/O занимает время и, следовательно, блокирует другие функции.
Рассмотрим сценарий, в котором мы запрашиваем user1 и user2 из бекенда, а затем печатаем их на экране / в консоли. Ответ на этот запрос требует времени, но оба запроса пользовательских данных могут выполняться независимо и в одно и то же время.

Блокирование ввода-вывода
В методе блокировки запрос данных user2 не запускается до тех пор, пока данные user1 не будут напечатаны на экране.
Если это был веб-сервер, нам нужно было бы начать новый поток для каждого нового пользователя. Но JavaScript однопоточен (но он имеет однопоточный цикл событий, о котором мы поговорим чуть позже). Таким образом, это сделает JavaScript не очень подходящим для многопоточных задач.
Неблокирующий ввод-вывод
С другой стороны, используя неблокирующий запрос, вы можете инициировать запрос данных для user2, не дожидаясь ответа на запрос user1. Вы можете инициировать оба запроса параллельно.
Неблокирующий ввод-вывод устраняет необходимость многопоточности, поскольку сервер может обрабатывать несколько запросов одновременно.
Цикл событий JavaScript
Если у вас есть 26 минут, посмотрите отличное видео-объяснение Node Event Loop:
Если нету, вот пошаговое объяснение того, как работает Event Loop в JavaScript:

1. Посылаете main() в стек вызовов.
2. Посылаете console.log() в стек вызовов. Он запускается сразу и появляется.
3. Посылаете setTimeout(2000) в стек. setTimeout(2000) это — Node API. Когда мы его вызываем, мы регистрируем пару событие-коллбек. Событие будет ждать 2000 миллисекунд, а потом вызовет коллбек.
4. После регистрации, setTimeout(2000) появляется в стеке вызовов.
5. Теперь второй setTimeout(0) регистрируется таким же образом. Теперь у нас есть два API-интерфейса Node, ожидающих выполнения.
6. После ожидания 0 секунд setTimeout(0) перемещается в очередь выполнения коллбеков (callback queue), и то же самое происходит с setTimeout(2000).
7. В очереди выполнения коллбеков функции ждут, когда стек вызовов будет пустым, потому что только одна функция может выполняться одновременно. Это обеспечивает event loop.
8. Вызывается последняя console.log(), а main() вызывается из стека вызовов.
9. Цикл событий видит, что стек вызовов пуст, а очередь обратного вызова — нет. Таким образом, он перемещает обратные вызовы (по порядку) в стек вызовов для выполнения.
Npm

Это библиотеки, построенные сообществом. Они решат большинство часто встречающихся проблем. npm (менеджер пакетов Node) содержит пакеты, которые вы можете использовать в своих приложениях, чтобы сделать вашу разработку более быстрой и эффективной.
Require
Require исполняет три функции:
Загружает модули, поставляемые в комплекте с Node.js, например из файловой системы или HTTP, из API Node.js.
Загружает сторонние библиотеки, такие как Express и Mongoose, которые вы устанавливаете из npm.
Позволяет создавать собственные файлы и делить проект на модули.
Require — это функция, и она принимает параметр «путь» и возвращает module.exports.
Node модули
Node модули это — многоразово используемые блоки кода, существование которых не случайно не влияет на другой код.
Вы можете написать свои собственные модули и использовать их в различных приложениях. Node.js имеет набор встроенных модулей, которые вы можете использовать без специальной установки.
V8 ускоряет JavaScript, используя C ++
V8 – движок с открытым исходным кодом, написанный на C ++.
JavaScript -> V8 (C ++) -> машинный код
V8 реализует сценарий ECMAScript, как указано в ECMA-262. ECMAScript был создан Ecma International для стандартизации JavaScript.
V8 может работать автономно или может быть встроен в любое приложение C ++. Благодаря этому, вы можете написать свой собственный код на C ++, и сделать его доступным для JavaScript.
События
События – это все, что произошло в нашем приложении, и на что мы можем ответить.
В Node есть два типа событий:
- Системные события: ядро C ++ из библиотеки libuv. (Например, окончание чтение файла).
- Пользовательские события: ядро JavaScript.
Пишем Hello World в Node.js
Почему бы и нет?
Создайте файл app.js и добавьте к нему следующее.
console.log («Hello World!»);
Откройте терминал Node, измените каталог на папку, в которой сохранен файл, и запустите node app.js.
Вуаля — вы только что написали «Hello World» в Node.js.
Существует огромное количество ресурсов, которые вы можете использовать, чтобы узнать больше о Node.js, включая freeCodeCamp.org.
Все про Node.js: зачем писать бэкенд на JavaScript и сколько за это платят

Node.js — это среда выполнения кода JavaScript вне браузера, которая позволяет писать серверный код для веб-страниц и веб-приложений, а также для программ командной строки.
Node.js — не отдельный язык программирования, а платформа для использования JavaScript на стороне сервера. С помощью платформы можно работать с файлами, сетью, базами данных и другими системными ресурсами на сервере.
Если говорить о языке, то как для фронтенда, так и для бэкенда используется один и тот же JavaScript. Разница только в наборе API, которые используют фронтендеры и бэкендеры. Браузерный JavaScript использует Web API, которые обеспечивают доступ к DOM и пользовательскому интерфейсу страниц и веб-приложений. Серверный JavaScript использует API, обеспечивающие доступ к файловой системе приложений, HTTP-запросам, потокам.
Node.js-разработчик — с нуля до трудоустройства за 10 месяцев
- Постоянная поддержка от наставника и учебного центра
- Помощь с трудоустройством
- Готовое портфолио к концу обучения
- Практика с первого урока
Вы получите именно те инструменты и навыки, которые позволят вам найти работу
Краткая история Node.js
Платформа Node.js была представлена в 2009 году — ее создал инженер Райан Дал, а спонсором разработки выступила компания Joyent. Она известна поддержкой опенсорсных проектов, включая Node.js, Illumos, SmartOS.
Для создания Node.js Райан Дал использовал движок V8. Платформа реализована с низкоуровневой неблокирующей моделью ввода/вывода, которая построена на событийно-ориентированной модели. Это означает, что Node.js может обрабатывать несколько запросов одновременно, без блокировки других операций.
В конце 2014 года инженер Федор Индутный, который входил в основную команду разработчиков платформы, создал популярный форк Node.js — io.js. Форк появился из-за недовольства разработчиков политикой компании Joyent.
Платформа io.js превосходила Node.js в производительности, но создатели форка уже в 2015 году решили воссоединиться с Node.js, чтобы влиять на развитие основной платформы. В настоящее время разработкой формально руководит Node.js Foundation.
Где используется Node.js
Создание серверных приложений
Node.js позволяет разрабатывать мощные и масштабируемые серверные приложения. Платформу используют для создания веб-серверов, API, приложений реального времени, других серверных приложений, SSR для React и других фронтенд-фреймворков.
Веб-разработка
С помощью Node.js создавать полноценные веб-приложения, работать с базами данных, управлять маршрутизацией и обработкой запросов от клиентов.
Node.js хорошо подходит для разработки Real Time Applications — веб-приложений, реагирующих на действия пользователя в режиме реального времени. Например, это может быть онлайн-редактор типа Google Docs, который позволяет работать над одним документом нескольким пользователям одновременно.
Потоковая передача данных
Node.js отлично справляется с потоковой передачей данных, особенно при работе с большими объемами данных или в режиме реального времени. Это делает платформу полезной для разработки систем обработки потоков данных, стримингового видео, чатов и других приложений, требующих эффективной передачи данных.
Инструменты разработки
Node.js также используется для создания сборщиков модулей, сред разработки, средств автоматизации задач (например, сборки проекта, запуска тестов) и других инструментов, упрощающих разработку и работу с JavaScript-кодом.
Интернет вещей (IoT)
Node.js предоставляет возможности для связи с устройствами, обработки данных с датчиков, управления и мониторинга устройств, а также интеграции с облачными сервисами. Для этого есть программная среда Espruino, с помощью которой можно разрабатывать встраиваемые системы и интернет вещей (IoT) на базе микроконтроллеров. Она также основана на языке JavaScript.
Командная строка
Node.js также может быть использован для создания командных инструментов и скриптов на сервере. Платформа предоставляет доступ к системным ресурсам и позволяет автоматизировать задачи в командной строке.
Микросервисная архитектура
Node.js подходит для построения микросервисных архитектур, где отдельные компоненты системы могут быть реализованы как отдельные сервисы, взаимодействующие друг с другом через API.
Зачем изучать Node.js
Выбор серверного JavaScript для бэкенда обеспечивает проекту ряд преимуществ:
- JavaScript входит в число самых популярных языков программирования, а изучив Node.js у вас будет возможность использовать язык не только для создания веб-страниц, но и для разработки серверных приложений.
- Рост эффективности разработки благодаря использованию одного языка для фронтенда и бэкенда и возможности переиспользования кода.
- В Node.js есть возможность использовать npm — самый большой пакетный менеджер.
- Node.js использует асинхронную модель выполнения, что позволяет эффективно обрабатывать множество запросов одновременно (до 10000 активных соединений) без блокировки.
- Node.js позволяет создавать мощные серверные приложения, которые могут обрабатывать запросы от клиентов, работать с базами данных, обрабатывать файлы и многое другое.
Чем бэкенд на JavaScript отличается от PHP и Python
Если в браузере JavaScript тотально доминирует, и конкурентов этого языка на фронтенде не видно даже на горизонте, то в бэкенд-разработке ситуация другая. Здесь JS конкурирует с PHP, Python и другими языками.
Бэкенд на JavaScript уступает PHP в популярности. На PHP написаны самые популярные системы управления контентом, включая WordPress, Joomla!, Drupal. Только на WordPress работает около трети всех сайтов в интернете.
PHP не позволяет из коробки писать асинхронный код, поэтому для каждого клиента запускается отдельный процесс. В Node.js с этим проще — благодаря асинхронной модели можно обрабатывать по несколько запросов в базу данных одновременно.
Python считается одним из лучших языков для изучения программирования. Python универсальный: его используют как в веб-разработке, так и в Data Science, Machine Learning и других сферах. Node.js более «заточен» под веб-разработку, особенно под создание серверных приложений, веб-сервисов и API.
Если вам принципиальна скорость обработки данных и необходимо обрабатывать сложные вычисления, стоит выбирать Python, так как у него лучше производительность. Для более быстрой обработки Python использует мощные библиотеки, вроде NumPy и Pandas.
Сколько зарабатывают Node.js-разработчики
По данным сервиса «Хабр Карьера» на вторую половину 2022 года, медианная зарплата JavaScript разработчика составляет 150 тыс. рублей в месяц. В эту статистику входят зарплаты как фронтенд-, так и бэкенд-разработчиков на JS.
В июле 2023 года при запросе Node.JS на hh.ru выдается около 1100 вакансий в России. 400 вакансий предлагают зарплату от 100 тыс. рублей до 200 тыс. рублей. Еще 164 вакансии — с зарплатой до 330 тыс. рублей, 88 вакансий — до 430 тыс. рублей, 50 — до 500 тыс. рублей и 26 вакансий — с заработной платой более 500 тыс. рублей в месяц.
Профессия «Node.js-разработчик»
- Освойте платформу Node.JS и начните использовать JavaScript для работы с бэкендом
- Научитесь использовать современные инструменты для создания бэкенд-приложений, включая Express и Fastify
- Получите возможность стать Fullstack-разработчиком и повысить свою ценность на рынке труда
Как установить Node.js
- Перейдите на страницу загрузки на официальном веб-сайте Node.js
- Здесь вы увидите два варианта: LTS и Current. Рекомендуем выбрать версию LTS (Long-Term Support), так как она более стабильная и имеет длительную поддержку.
- Далее необходимо выбрать версию для той операционной системы, которая вам подходит: Windows, macOS, Linuх. Либо есть возможность скачать официальный Node.js Docker Image, а также использовать Node.js c дополнительными платформами, например, Linux on Power LE Systems.
- После выбора версии начнется загрузка установочного файл Node.js. Дождитесь завершения загрузки, запустите установочный файл и следуйте инструкциям мастера установки.
- После завершения установки откройте терминал и в командной строке введите команду node -v . Если Node.js успешно установлен, вы увидите версию Node.js, например, v20.2.0 (номер версии может отличаться).
Мы также написали более подробную инструкцию по установке Node.js, посмотреть ее можно в GitHub.
Пишем первый код на Node.js
Давайте попробуем создать очень простую программу на Node.js. Для начала создайте новую папку под ваш проект. Далее откройте любой текстовый редактор и создайте файл с расширением js. Например, hello.js.
Откройте файл hello.js в текстовом редакторе и напишите следующий код:
console.log("Hello, World!");
После этого сохраните файл с кодом, который у вас получился.
Далее откройте командную строку и перейдите в папку вашего проекта. В командной строке введите следующую команду для выполнения программы:
node hello.js
После выполнения команды вы увидите вывод «Hello, World!» в консоли.
Эксперты о перспективах Node.js
Мы поговорили с тремя экспертами Node.js и выяснили их мнение о том, как долго будет популярна платформа, почему стоит ее изучать и сколько времени нужно учиться бэкенду с нуля до джуниора.
Игорь Камышев: судя по тенденциям, Node.js станет только популярнее

Игорь Камышев, разработчик веб-приложений в Aviasales. Разрабатывает экосистему библиотек для Node.js Solid Soda.
Почему стоит изучать Node.js. Node.js — необычная технология. Современная экосистема JavaScript создавалась непрограммистами, из-за этого в ней очень много свежих и необычных идей. Начать писать приложения на Node.js проще, чем на Java, Ruby или PHP. Плюс, это достаточно зрелая платформа, многие проблемы уже решены, а лучшие подходы известны и описаны.
Перспективы бэкенда на JavaScript. Любой бэкенд может быть написан на любом языке. Вопрос только в скорости разработки и надежности этого решения. Приложения для Node.js можно быстро писать, но для обеспечения надежности нужно постараться. Важно понимать, что JavaScript — это язык со слабой динамической типизацией, чтобы это компенсировать, нужно заранее продумать архитектуру приложения и потратить больше времени на написание тестов.
На мой взгляд, Node.js подойдет для очень широкого класса бэкендов. Начиная от интернет-магазинов и заканчивая образовательными сервисами. Судя по тенденциям роста, Node.js будет становиться только популярнее. Сложно оценить, когда этот рост прекратится, но сейчас — это факт.
За какое время можно изучить Node.js. Node.js — супер-минималистичная платформа. По сути, чтобы разобраться с ней, достаточно выучить JavaScript и прочитать 10 страниц документации Node.js. Я полагаю, если вы никогда прежде не сталкивались с программированием, то за 5-6 месяцев можно освоить все что необходимо и стать полноправным членом команды».
Андрей Мелихов: рынок сейчас остро нуждается в грамотных сильных разработчиках с бэкграундом из других языков

Андрей Мелихов, программист-эксперт в компании Yandex Cloud, ведущий подкаста «Девшахта»
Почему стоит изучать Node.js Как бы не хотели многие, сайты все еще требуют серверного рендеринга. Это не только SEO-задачи, но и мобильный трафик. Если мы не хотим усложнять себе жизнь и используем один и тот же код на сервере и клиенте, то наш практически единственный выбор — это JavaScript.
Конечно, есть и различная экзотика, компилируемая в JS, но за исключением TypeScript, все это пока достаточно сложно воспринимать серьезно. Итак, нам нужен JS на сервере, и тут основной игрок — Node.js. Да, стоит напомнить, что есть и другие решения, позволяющие исполнять JS за пределами браузера, но на фоне Node.js их доля незаметна. Это первое.
Второе — в какой-то момент необходимо работать с данными, хранимыми на сервере. Мне кажется, что любой веб-разработчик хотя бы на базовом уровне должен понимать, как это все устроено. И здесь Node.js отличный выбор, он позволяет создать полноценный веб-сервер с минимальным порогом вхождения.
Третье. Несмотря на все насмешки и недоверие, Node.js дорос до состояния практически взрослого инструмента и продолжает развиваться. Сегодня мы наконец-то имеем приличный инструментарий, статическую типизацию и даже один хороший фреймворк (Nest). Можно смело рекомендовать Node.js в качестве серверного решения для больших долгоживущих нагруженных проектов.
Перспективы бэкенда на JavaScript. Если говорить именно о языке, то мы видим, что JS постепенно становится целью сборки, а не языком, на котором пишут код. И в случае Node.js главная причина тут TypeScript, так как в отличие от браузера нам не нужно транспилировать JS в JS — мы полностью контролируем среду исполнения. Однако те возможности, которые нам дает TypeScript, гораздо больше, чем просто синтаксический сахар.
И если взять современные инструменты, такие как Nest, то они эти возможности активно используют. Современный проект на Node.js — это статическая типизация, Dependency Injection, паттерны проектирования. Возможно, за этим теряется простота и легкость JavaScript, но вместо этого приходит надежность и упрощение разработки и поддержки в больших проектах.
Неожиданно, но JavaScript стал языком для всего. Сервер, браузер, мобильные телефоны, десктопные приложения, IoT — везде JavaScript неплохо себя чувствует. Совершенно новым направлением оказались AWS-лямбды (serverless), в которых JavaScript тоже отлично себя проявил. Так что да, разработчики будут востребованы. Но если говорить о сервере, то мне кажется, рынок сейчас остро нуждается в грамотных сильных разработчиках с бэкграундом из других языков.
С чего начать изучать Node.js. Начать стоит с изучения UNIX и в целом основ работы компьютерных сетей. После этого можно попробовать написать простое приложение на Node.js, лучше без фреймворков (в том числе без Express). Поняв, что такое TCP/UDP и HTTP/HTTPS, можно уже попробовать написать полноценный бэкенд на Express, отдающий данные по AJAX и шаблонизирующий HTML. Также, конечно, придется разобраться с Nginx или HAProxy, понять, что такое балансировка. Очень неплохо хотя бы на минимальном уровне понять, что такое Docker и зачем он нужен.
Следующим шагом я бы порекомендовал погрузиться в TypeScript и попробовать Nest. Неплохим вариантом является изучение связки Angular + Nest, так как Nest создан под сильным влиянием Angular и реализует сходные концепции.
Строго рекомендую книгу Node.js Design Patterns от Mario Casciaro.
Алексей Золотых: на рынке труда не хватает разработчиков на Node.js

Алексей Золотых, тимлид в МойОфис, соорганизатор конференции HolyJS
Почему стоит изучать Node.js. В последнее время Node.js становится все более взрослой технологией. Появляются серьезные инструменты для отладки, трейсинга и выявления других проблем. В сообществе накапливается экспертиза. Движение в сторону микросервисов нивелирует недостатки в отсутствие статической типизации путем уменьшения сложности. И да, для больших проектов у нас все еще есть TypeScript.
Думаю, что у Node.js точно есть будущее, и точно есть куда расти. Вместе с тем порог входа очень низкий. Это позволяет не думать про технологии и сложность, а просто сосредоточиться на продукте.
Перспективы бэкенда на JavaScript. Я изначально против привязки к технологиям. Хороший инженер должен выбирать технологию под задачу, а не пытаться быть парнем с молотком, для которого все вокруг гвозди. На данный момент у ноды приличная скорость в некоторых аспектах, низкий порог входа, высокая популярность и куча библиотек для всего. С другой стороны, не решены многие вопросы. Но думаю, что это звучит как вызов.
За какое время можно изучить Node.js. Все индивидуально. Если вы любопытны и въедливы, то думаю, что не менее полугода.
Профессия «Node.js-разработчик»
- Освойте платформу Node.JS и начните использовать JavaScript для работы с бэкендом
- Научитесь использовать современные инструменты для создания бэкенд-приложений, включая Express и Fastify
- Получите возможность стать Fullstack-разработчиком и повысить свою ценность на рынке труда
Node.js
Node.js (Node) — это платформа с открытым исходным кодом для работы с языком JavaScript, построенная на движке Chrome V8. Она позволяет писать серверный код для веб-приложений и динамических веб-страниц, а также программ командной строки. В основе платформы — событийно-управляемая модель с неблокирующими операциями ввода-вывода, что делает ее эффективной и легкой.

Освойте профессию «Frontend-разработчик»
Платформу разработал Райан Дал, программист из Америки, в 2009 году. До появления Node.js приложения, которые написаны на языке программирования JavaScript, можно было запускать только в браузере. С появлением платформы стало возможно писать на JavaScript не только в браузере, но и на сервере.
Что такое Node.js и как она работает
Node.js работает на движке V8, транслирующем JavaScript в машинный код. Простыми словами, Node.js — это приложение на C++, которое получает на входе код JavaScript и выполняет его. Чтобы взаимодействовать с устройствами ввода-вывода на компьютере, в платформе предусмотрен собственный интерфейс на C++. Таким образом, платформа превращает специализированный скриптовый язык JavaScript в язык общего назначения, поэтому на Node.js можно писать любые компьютерные программы. Платформа позволяет пользоваться единым языком JavaScript для написания кода и на стороне клиента (Frontend), и на сервере (Backend). Эти возможности Node.js важны для разработки приложений реального времени, которые основаны на событиях.
Профессия / 9 месяцев
Frontend-разработчик
Создавайте интерфейсы сервисов, которыми пользуются все

Для чего нужна Node.js
Платформу используют fronted-разработчики, backend-разработчики и другие. Она позволяет написать программу для разных ОС: Linux, OS X и Windows, может использоваться для создания API. Также Node.js применяется для разработки кросс-платформенных приложений: например, списка задач, который должен работать на разных платформах, синхронизировать данные в реальном времени и отправлять на мобильное устройство. Node.js используется при создании сервисов с постоянным обменом информацией с пользователем: социальных сетей, онлайн-игр, чатов, систем совместной работы над проектом, онлайн-редакторов текста и пр.
Node.js лежит в основе Internet of Things, или просто IoT. Платформа помогает управлять приборами и создавать серверы, способные одновременно обрабатывать большое количество запросов.
Многие крупные компании используют Node.js. Например, eBay и веб-версия PayPal в процессе перехода, а LinkedIn, полностью отказавшиеся от Ruby on Rails в пользу Node.js еще в 2012 году, заявили о 20-кратном ускорении 27 серверов. Среди других известных компаний — Yahoo, Netflix, Uber, Walmart, Google и многие другие.

Станьте Frontend-разработчиком
и создавайте интерфейсы сервисов, которыми пользуются все
Как выглядит код
Пример создания и запуска HTTP-сервера на Node.js, выдающего «Hello, World!»:
const http = require('http'); const requestListener = function (req, res) < res.writeHead(200); res.end('Hello, World!'); >const server = http.createServer(requestListener); server.listen(8080);
Причины популярности
Высокая скорость. JavaScript-код, который выполняется в среде Node.js, может быть в несколько раз быстрее, чем написанный на языках вроде Ruby или Python. В Node.js используется модель асинхронного программирования. Модель позволяет продолжить обработку других задач, не дожидаясь завершения передачи данных. Когда требуется выполнить операцию ввода-вывода вроде доступа к файловой системе или базе данных, Node.js не блокирует главный поток ожиданием результатов. Платформа инициирует ее выполнение и продолжает выполнять другие задачи, пока результаты предыдущей операции не будут получены.
Универсальность и гибкость. В Node.js выполняется код, который написан на JavaScript. Это означает, что frontend-разработчики, которые уже используют JavaScript в браузере, могут писать и клиентский, и серверный код на привычном языке программирования, не изучая инструмент с нуля. В Node.js можно быстро переходить на новые стандарты ECMAScript по мере их реализации. Новые возможности языка становятся доступны сразу после установки поддерживающей их версии Node.js.
Читайте также С чего начать учить JavaScript? 5 шагов для старта
Большое количество модулей и библиотек. Экосистема Node.js стремительно развивается благодаря менеджеру пакетов NPM. Он содержит более 500 000 модулей и библиотек open-source, которые находятся в свободном доступе. Также постоянно появляются новые.
Работа на движке Chrome V8. Node.js работает на JavaScript-движке V8 от Google. V8 — движок JavaScript с открытым исходным кодом, распространяемый по лицензии BSD. Он применяется в браузерах на основе Chromium. Это означает, что в Node.js использованы наработки тысяч инженеров. Движок написан на C++, имеет открытый исходный код и продвинутые библиотеки.

Как установить Node.js
Установка Node не должна вызвать проблем даже у новичков, ниже приведен алгоритм действий на Windows и OS X.
Установка Node.js на Windows и Linux
Первый шаг — установка консоли. На Windows уже предустановлен терминал cmd.exe, но как основное «место работы» он не подходит. В качестве аналога используется эмулятор консоли, например cmder. После этого шага с официального сайта Node.js необходимо скачать последнюю версию платформы.

После запуска инсталлятора Node.js устанавливается в интерактивном режиме. В конце установки необходимо проверить версию с помощью двух команд: node -v и npm -v.
В операционных системах на основе Linux Node.js устанавливается с помощью пакетного менеджера.
Установка Node.js на OS X
Алгоритм мало отличается от установки на Windows; разница лишь в том, что предварительные шаги не нужны. С официального сайта нужно скачать последнюю доступную версию, установить ее и можно сразу пользоваться.

Frontend-разработчик
Научитесь создавать удобные и эффектные сайты, сервисы и приложения, которые нужны всем. Сегодня профессия на пике актуальности: в России 9000+ вакансий, где требуется знание JavaScript.

Статьи по теме:
- Асинхронное программирование
- Angular
- Heroku
The Node.js Event Loop, Timers, and process.nextTick()
The event loop is what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible.
Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background. When one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed. We’ll explain this in further detail later in this topic.
Event Loop Explained
When Node.js starts, it initializes the event loop, processes the provided input script (or drops into the REPL, which is not covered in this document) which may make async API calls, schedule timers, or call process.nextTick() , then begins processing the event loop.
The following diagram shows a simplified overview of the event loop’s order of operations.
┌───────────────────────────┐ ┌─>│ timers │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming: │ │ │ poll │
Each box will be referred to as a "phase" of the event loop.
Each phase has a FIFO queue of callbacks to execute. While each phase is special in its own way, generally, when the event loop enters a given phase, it will perform any operations specific to that phase, then execute callbacks in that phase's queue until the queue has been exhausted or the maximum number of callbacks has executed. When the queue has been exhausted or the callback limit is reached, the event loop will move to the next phase, and so on.
Since any of these operations may schedule more operations and new events processed in the poll phase are queued by the kernel, poll events can be queued while polling events are being processed. As a result, long running callbacks can allow the poll phase to run much longer than a timer's threshold. See the timers and poll sections for more details.
There is a slight discrepancy between the Windows and the Unix/Linux implementation, but that's not important for this demonstration. The most important parts are here. There are actually seven or eight steps, but the ones we care about — ones that Node.js actually uses - are those above.
Phases Overview
- timers: this phase executes callbacks scheduled by setTimeout() and setInterval() .
- pending callbacks: executes I/O callbacks deferred to the next loop iteration.
- idle, prepare: only used internally.
- poll: retrieve new I/O events; execute I/O related callbacks (almost all with the exception of close callbacks, the ones scheduled by timers, and setImmediate() ); node will block here when appropriate.
- check: setImmediate() callbacks are invoked here.
- close callbacks: some close callbacks, e.g. socket.on('close', . ) .
Between each run of the event loop, Node.js checks if it is waiting for any asynchronous I/O or timers and shuts down cleanly if there are not any.
Phases in Detail
timers
A timer specifies the threshold after which a provided callback may be executed rather than the exact time a person wants it to be executed. Timers callbacks will run as early as they can be scheduled after the specified amount of time has passed; however, Operating System scheduling or the running of other callbacks may delay them.
Technically, the poll phase controls when timers are executed.
For example, say you schedule a timeout to execute after a 100 ms threshold, then your script starts asynchronously reading a file which takes 95 ms:
const fs = require('fs'); function someAsyncOperation(callback) // Assume this takes 95ms to complete fs.readFile('/path/to/file', callback); > const timeoutScheduled = Date.now(); setTimeout(() => const delay = Date.now() - timeoutScheduled; console.log(`$delay>ms have passed since I was scheduled`); >, 100); // do someAsyncOperation which takes 95 ms to complete someAsyncOperation(() => const startCallback = Date.now(); // do something that will take 10ms. while (Date.now() - startCallback 10) // do nothing > >);
When the event loop enters the poll phase, it has an empty queue ( fs.readFile() has not completed), so it will wait for the number of ms remaining until the soonest timer's threshold is reached. While it is waiting 95 ms pass, fs.readFile() finishes reading the file and its callback which takes 10 ms to complete is added to the poll queue and executed. When the callback finishes, there are no more callbacks in the queue, so the event loop will see that the threshold of the soonest timer has been reached then wrap back to the timers phase to execute the timer's callback. In this example, you will see that the total delay between the timer being scheduled and its callback being executed will be 105ms.
To prevent the poll phase from starving the event loop, libuv (the C library that implements the Node.js event loop and all of the asynchronous behaviors of the platform) also has a hard maximum (system dependent) before it stops polling for more events.
pending callbacks
This phase executes callbacks for some system operations such as types of TCP errors. For example if a TCP socket receives ECONNREFUSED when attempting to connect, some *nix systems want to wait to report the error. This will be queued to execute in the pending callbacks phase.
poll
The poll phase has two main functions:
- Calculating how long it should block and poll for I/O, then
- Processing events in the poll queue.
When the event loop enters the poll phase and there are no timers scheduled, one of two things will happen:
- If the poll queue is not empty, the event loop will iterate through its queue of callbacks executing them synchronously until either the queue has been exhausted, or the system-dependent hard limit is reached.
- If the poll queue is empty, one of two more things will happen:
- If scripts have been scheduled by setImmediate() , the event loop will end the poll phase and continue to the check phase to execute those scheduled scripts.
- If scripts have not been scheduled by setImmediate() , the event loop will wait for callbacks to be added to the queue, then execute them immediately.
Once the poll queue is empty the event loop will check for timers whose time thresholds have been reached. If one or more timers are ready, the event loop will wrap back to the timers phase to execute those timers' callbacks.
check
This phase allows a person to execute callbacks immediately after the poll phase has completed. If the poll phase becomes idle and scripts have been queued with setImmediate() , the event loop may continue to the check phase rather than waiting.
setImmediate() is actually a special timer that runs in a separate phase of the event loop. It uses a libuv API that schedules callbacks to execute after the poll phase has completed.
Generally, as the code is executed, the event loop will eventually hit the poll phase where it will wait for an incoming connection, request, etc. However, if a callback has been scheduled with setImmediate() and the poll phase becomes idle, it will end and continue to the check phase rather than waiting for poll events.
close callbacks
If a socket or handle is closed abruptly (e.g. socket.destroy() ), the 'close' event will be emitted in this phase. Otherwise it will be emitted via process.nextTick() .
setImmediate() vs setTimeout()
setImmediate() and setTimeout() are similar, but behave in different ways depending on when they are called.
- setImmediate() is designed to execute a script once the current poll phase completes.
- setTimeout() schedules a script to be run after a minimum threshold in ms has elapsed.
The order in which the timers are executed will vary depending on the context in which they are called. If both are called from within the main module, then timing will be bound by the performance of the process (which can be impacted by other applications running on the machine).
For example, if we run the following script which is not within an I/O cycle (i.e. the main module), the order in which the two timers are executed is non-deterministic, as it is bound by the performance of the process:
// timeout_vs_immediate.js setTimeout(() => console.log('timeout'); >, 0); setImmediate(() => console.log('immediate'); >);$ node timeout_vs_immediate.js timeout immediate $ node timeout_vs_immediate.js immediate timeoutHowever, if you move the two calls within an I/O cycle, the immediate callback is always executed first:
// timeout_vs_immediate.js const fs = require('fs'); fs.readFile(__filename, () => setTimeout(() => console.log('timeout'); >, 0); setImmediate(() => console.log('immediate'); >); >);$ node timeout_vs_immediate.js immediate timeout $ node timeout_vs_immediate.js immediate timeoutThe main advantage to using setImmediate() over setTimeout() is setImmediate() will always be executed before any timers if scheduled within an I/O cycle, independently of how many timers are present.
process.nextTick()
Understanding process.nextTick()
You may have noticed that process.nextTick() was not displayed in the diagram, even though it's a part of the asynchronous API. This is because process.nextTick() is not technically part of the event loop. Instead, the nextTickQueue will be processed after the current operation is completed, regardless of the current phase of the event loop. Here, an operation is defined as a transition from the underlying C/C++ handler, and handling the JavaScript that needs to be executed.
Looking back at our diagram, any time you call process.nextTick() in a given phase, all callbacks passed to process.nextTick() will be resolved before the event loop continues. This can create some bad situations because it allows you to "starve" your I/O by making recursive process.nextTick() calls, which prevents the event loop from reaching the poll phase.
Why would that be allowed?
Why would something like this be included in Node.js? Part of it is a design philosophy where an API should always be asynchronous even where it doesn't have to be. Take this code snippet for example:
function apiCall(arg, callback) if (typeof arg !== 'string') return process.nextTick( callback, new TypeError('argument should be string') ); >The snippet does an argument check and if it's not correct, it will pass the error to the callback. The API updated fairly recently to allow passing arguments to process.nextTick() allowing it to take any arguments passed after the callback to be propagated as the arguments to the callback so you don't have to nest functions.
What we're doing is passing an error back to the user but only after we have allowed the rest of the user's code to execute. By using process.nextTick() we guarantee that apiCall() always runs its callback after the rest of the user's code and before the event loop is allowed to proceed. To achieve this, the JS call stack is allowed to unwind then immediately execute the provided callback which allows a person to make recursive calls to process.nextTick() without reaching a RangeError: Maximum call stack size exceeded from v8 .
This philosophy can lead to some potentially problematic situations. Take this snippet for example:
let bar; // this has an asynchronous signature, but calls callback synchronously function someAsyncApiCall(callback) callback(); > // the callback is called before `someAsyncApiCall` completes. someAsyncApiCall(() => // since someAsyncApiCall hasn't completed, bar hasn't been assigned any value console.log('bar', bar); // undefined >); bar = 1;The user defines someAsyncApiCall() to have an asynchronous signature, but it actually operates synchronously. When it is called, the callback provided to someAsyncApiCall() is called in the same phase of the event loop because someAsyncApiCall() doesn't actually do anything asynchronously. As a result, the callback tries to reference bar even though it may not have that variable in scope yet, because the script has not been able to run to completion.
By placing the callback in a process.nextTick() , the script still has the ability to run to completion, allowing all the variables, functions, etc., to be initialized prior to the callback being called. It also has the advantage of not allowing the event loop to continue. It may be useful for the user to be alerted to an error before the event loop is allowed to continue. Here is the previous example using process.nextTick() :
let bar; function someAsyncApiCall(callback) process.nextTick(callback); > someAsyncApiCall(() => console.log('bar', bar); // 1 >); bar = 1;Here's another real world example:
const server = net.createServer(() => <>).listen(8080); server.on('listening', () => <>);When only a port is passed, the port is bound immediately. So, the 'listening' callback could be called immediately. The problem is that the .on('listening') callback will not have been set by that time.
To get around this, the 'listening' event is queued in a nextTick() to allow the script to run to completion. This allows the user to set any event handlers they want.
process.nextTick() vs setImmediate()
We have two calls that are similar as far as users are concerned, but their names are confusing.
- process.nextTick() fires immediately on the same phase
- setImmediate() fires on the following iteration or 'tick' of the event loop
In essence, the names should be swapped. process.nextTick() fires more immediately than setImmediate() , but this is an artifact of the past which is unlikely to change. Making this switch would break a large percentage of the packages on npm. Every day more new modules are being added, which means every day we wait, more potential breakages occur. While they are confusing, the names themselves won't change.
We recommend developers use setImmediate() in all cases because it's easier to reason about.
Why use process.nextTick() ?
There are two main reasons:
- Allow users to handle errors, cleanup any then unneeded resources, or perhaps try the request again before the event loop continues.
- At times it's necessary to allow a callback to run after the call stack has unwound but before the event loop continues.
One example is to match the user's expectations. Simple example:
const server = net.createServer(); server.on('connection', conn => <>); server.listen(8080); server.on('listening', () => <>);Say that listen() is run at the beginning of the event loop, but the listening callback is placed in a setImmediate() . Unless a hostname is passed, binding to the port will happen immediately. For the event loop to proceed, it must hit the poll phase, which means there is a non-zero chance that a connection could have been received allowing the connection event to be fired before the listening event.
Another example is extending an EventEmitter and emitting an event from within the constructor:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter constructor() super(); this.emit('event'); > > const myEmitter = new MyEmitter(); myEmitter.on('event', () => console.log('an event occurred!'); >);You can't emit an event from the constructor immediately because the script will not have processed to the point where the user assigns a callback to that event. So, within the constructor itself, you can use process.nextTick() to set a callback to emit the event after the constructor has finished, which provides the expected results:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter constructor() super(); // use nextTick to emit the event once a handler is assigned process.nextTick(() => this.emit('event'); >); > > const myEmitter = new MyEmitter(); myEmitter.on('event', () => console.log('an event occurred!'); >);Copyright OpenJS Foundation and Node.js contributors. All rights reserved. The OpenJS Foundation has registered trademarks and uses trademarks. For a list of trademarks of the OpenJS Foundation, please see our Trademark Policy and Trademark List. Trademarks and logos not indicated on the list of OpenJS Foundation trademarks are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
