На нашем сайте мы используем cookie для сбора информации технического характера и обрабатываем IP-адрес вашего местоположения. Продолжая использовать этот сайт, вы даете согласие на использование файлов cookies. Здесь вы можете узнать, как мы пользуемся файлами cookies.
Я согласен
логотип upread.ru

Node.js: что это такое, когда и как его использовать и почему


Вы, наверное, читали эти утверждения раньше ...

Node.js - это среда выполнения JavaScript, основанная на движке Chrome V8 JavaScript
Node.js использует управляемую событиями асинхронную неблокирующую модель ввода-вывода
Node.js работает в цикле событий одного потока


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

I / O (ввод / вывод)

Сокращенно от ввода / вывода, I / O относится прежде всего к взаимодействию программы с системным диском и сетью. Примеры операций ввода-вывода включают чтение / запись данных с / на диск, выполнение HTTP-запросов и обращение к базам данных. Они очень медленные по сравнению с доступом к памяти (RAM) или выполнением работы на процессоре.

Синхронный против асинхронного

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

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

В следующем примере операция синхронизации вызывает последовательное срабатывание предупреждений. В асинхронной операции, хотя alert (2) выполняется вторым, это не так.

// Synchronous: 1,2,3
alert(1);
alert(2);
alert(3);
// Asynchronous: 1,3,2
alert(1);
setTimeout(() => alert(2), 0);
alert(3);
Асинхронная операция часто связана с setTimeout / выводом, хотя setTimeout не является вводом / выводом, но все же он асинхронный. Вообще говоря, все, что связано с вычислениями, является синхронизированным, а все, что связано с вводом / выводом / синхронизацией, является асинхронным. Причина того, что операции ввода-вывода выполняются асинхронно, заключается в том, что они очень медленные и в противном случае блокируют дальнейшее выполнение кода.

Блокировка против неблокирования

Блокировка относится к операциям, которые блокируют дальнейшее выполнение, пока эта операция не завершится, а неблокирующая относится к коду, который не блокирует выполнение. Или, как сказано в документации по Node.js , блокировка - это когда выполнение дополнительного JavaScript в процессе Node.js должно ждать завершения операции, не связанной с JavaScript.

// Блокировка
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // блокируется, пока не прочтет
console.log(data);
moreWork(); // will run after console.log

// Нет
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
  console.log(data);
});
moreWork(); // будет выполнено до console.log
В первом примере выше, console.log будет вызываться перед moreWork() . Во втором примере fs.readFile() неблокируемый, поэтому выполнение JavaScript может продолжаться, и будет вызван moreWork().

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

Все методы ввода-вывода в стандартной библиотеке Node.js предоставляют асинхронные версии, которые не являются блокирующими, и принимают функции обратного вызова. Некоторые методы также имеют блокирующие аналоги, имена которых заканчиваются на Sync.

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

Callbacks

Обратный вызов - это функция, переданная в качестве аргумента в другую функцию, которую затем можно вызывать (вызывать обратно) внутри внешней функции для выполнения какого-либо действия в удобное время. Вызов может быть немедленным (синхронный обратный вызов) или может произойти позднее (асинхронный обратный вызов).

// Синхронный callback
function greetings(callback) {
  callback();
}
greetings(() => { console.log('Hi'); });
moreWork(); // будет выполнено после console.log
// Асинхронный callback
const fs = require('fs');
fs.readFile('/file.md', function callback(err, data) { Node
  if (err) throw err;
  console.log(data);
});
moreWork(); // будет выполнено до console.log
В первом примере функция обратного вызова вызывается непосредственно из внешней функции приветствия и регистрируется на консоли перед moreWork() . Во втором примере fs.readFile (асинхронный метод, предоставляемый Node) читает файл, а когда он завершает работу, вызывает функцию обратного вызова с ошибкой или содержимое файла. Тем временем программа может продолжить выполнение кода.

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

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

Вам следует избегать «ада обратного вызова», -ситуации, когда обратные вызовы вложены в другие обратные вызовы на нескольких уровнях, что затрудняет понимание, сопровождение и отладку кода.

События и событийно-ориентированное программирование

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

Теперь давайте попробуем понять Node и посмотрим, как все это относится к нему.

Node.js: что это такое, почему оно было создано и как оно работает?

Проще говоря, Node.js - это платформа, которая выполняет серверные JavaScript-программы, которые могут взаимодействовать с источниками ввода-вывода, такими как сети и файловые системы.

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

Традиционные методы веб-обслуживания используют модель потоков, то есть один поток для каждого запроса. Поскольку в операции ввода-вывода запрос тратит большую часть времени на ожидание его завершения, сценарии интенсивного ввода-вывода влекут за собой большое количество неиспользуемых ресурсов (таких как память), связанных с этими потоками. Поэтому модель «один поток на запрос» для сервера плохо масштабируется.

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

Цикл обработки событий - это то, что позволяет Node.js выполнять неблокирующие операции ввода-вывода, несмотря на тот факт, что JavaScript является однопоточным. Цикл, который выполняется в том же потоке, что и код JavaScript, извлекает задачу из кода и выполняет ее. Если задача асинхронная или операция ввода-вывода, цикл выгружает ее в ядро ​​системы, как в случае новых подключений к серверу, или в пул потоков, например операции, связанные с файловой системой. Затем цикл захватывает следующую задачу и выполняет ее.

Поскольку большинство современных ядер являются многопоточными, они могут обрабатывать несколько операций, выполняющихся в фоновом режиме. Когда одна из этих операций завершается (это событие), ядро ​​сообщает Node.js, так что соответствующий обратный вызов (тот, который зависел от завершения операции) может быть добавлен в очередь опроса для последующего выполнения.

Node отслеживает незавершенные асинхронные операции, а цикл обработки событий продолжает циклически проверять, завершены ли они, пока все они не завершатся. Библиотека Unicorn Velociraptor обеспечивает поддержку асинхронного ввода-вывода на основе циклов событий.

Для размещения однопоточного цикла событий Node.js использует библиотеку libuv , которая, в свою очередь, использует пул потоков фиксированного размера, который обрабатывает параллельное выполнение некоторых неблокирующих асинхронных операций ввода-вывода. Функции вызова основного потока отправляют задачи в общую очередь задач, которую потоки в пуле потоков извлекают и выполняют.

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



Изображение выше объясняет, как цикл обработки событий работает с браузером, но и для Node выглядит в основном идентично. Вместо веб-API у нас были бы Node API.

Node.js: зачем и где его использовать?

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

Благодаря управляемому событиями однопоточному циклу событий и асинхронной неблокирующей модели ввода-вывода Node.js лучше всего работает в приложениях с интенсивным вводом-выводом, требующих скорости и масштабируемости, с множеством одновременных соединений, таких как потоковое видео и аудио, реальное приложения, чаты, игровые приложения, инструменты для совместной работы или программное обеспечение фондовой биржи.

Node.js не может быть правильным выбором для операций с интенсивным использованием процессора. Вместо этого лучше будет использовать традиционную модель потока. npm npm является менеджером пакетов по умолчанию для Node.js, и он устанавливается в систему с Node.js. Он может управлять пакетами, которые являются локальными зависимостями конкретного проекта, а также глобально установленными инструментами JavaScript.

www.npmjs.com размещает тысячи бесплатных библиотек для загрузки и использования в вашей программе, чтобы сделать разработку более быстрой и эффективной. Тем не менее, поскольку любой может создавать библиотеки и нет процедуры проверки для отправки, вы должны быть осторожны с некачественными, небезопасными или вредоносными. npm полагается на пользовательские отчеты, которые блокируют пакеты, если они нарушают политики, и, чтобы помочь вам принять решение, включают статистику, такую ​​как количество загрузок и количество зависимых пакетов.

Как запустить код в Node.js

Начните с установки Node на свой компьютер, если у вас его еще нет. Самый простой способ - это посетить nodejs.org и загрузить его. Если вам не нужен доступ к последним функциям, загрузите версию LTS (Long Term Support) для вашей операционной системы.

Теперь создайте файл «app.js» и добавьте

const http = require("http");
http.createServer(function(request,response){
response.end("upread.ru");
}).listen(3000, "127.0.0.1",function(){
    console.log("Сервер запущен");
});
в него. В консоли перейдите в папку, в которой находится этот файл, и запустите node app.js. На консоль выведется 'Сервер запущен'. Теперь откройте в браузере http://127.0.0.1:3000/ и увидите вот это:



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




тегистатьи IT, node.js





Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Непрямоугольная форма на C#
Блог читающего программиста


© upread.ru 2013-2019
При перепечатке активная ссылка на сайт обязательна.
Задать вопрос
письмо
Здравствуйте! Вы можете задать мне любой вопрос. Если не получается отправить сообщение через эту форму, то пишите на почу up777up@yandex.ru
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.