Что такое Node.js? [закрыто]


506

Я не в полной мере получить то , что Node.js это все о. Может быть, это потому, что я в основном разработчик веб-приложений для бизнеса. Что это такое и какая польза от этого?

Мое понимание до сих пор таково:

  1. Модель программирования основана на событиях, особенно на способах ввода-вывода .
  2. Он использует JavaScript и парсер V8 .
  3. Он может быть легко использован для создания параллельных серверных приложений.

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

Ответы:


213

Я думаю, что преимущества:

  1. Веб-разработка на динамическом языке (JavaScript) на невероятно быстрой виртуальной машине (V8). Это намного быстрее, чем Ruby, Python или Perl.

  2. Возможность обрабатывать тысячи одновременных соединений с минимальными издержками на один процесс.

  3. JavaScript идеально подходит для циклов событий с функциональными объектами первого класса и замыканиями. Люди уже знают, как использовать его таким образом, используя его в браузере для ответа на инициируемые пользователем события.

  4. Многие уже знают JavaScript, даже те, кто не претендует на звание программистов. Это, пожалуй, самый популярный язык программирования.

  5. Использование JavaScript на веб-сервере, а также в браузере уменьшает несоответствие импеданса между двумя средами программирования, которые могут передавать структуры данных через JSON, которые работают одинаково с обеих сторон уравнения. Дублирующий код проверки формы может быть передан между сервером и клиентом и т. Д.


1
@postfuturist: На самом деле он хорошо работает против множества альтернатив. Во многих случаях она довольно удобна для Java 6. Ухоженная!
Адам Кроссленд

1
@postfuturist Я думаю, что вы сравнили с Java 6-Xint. Попробуйте сравнить с java 6 -сервером
fedesilva

@iJK yammer.com - рабочее приложение для node.js
Жерар Банасиг

1
Забавно, я писал JScript на ASP 10 лет назад, поэтому я мог (а) избежать ужасного VBScript, (б) использовать один и тот же язык на клиенте и сервере, и (в) повторно использовать свою и чужие библиотеки JS для обработки строк ... и т. д.
Энтони Куинн

4
@ Почему вы редактировали этот пост только для "Legacy фигня"? Я не думаю, что 212 человек проголосовали бы за этот пост, если бы вы написали это с самого начала.
Жюльен Фуйе

619

Я использую Node.js на работе и считаю его очень мощным. Вынужденный выбрать одно слово для описания Node.js, я бы сказал «интересный» (что не является чисто положительным прилагательным). Сообщество является ярким и растущим. JavaScript, несмотря на его странности, может быть отличным языком для написания кода. И вы будете ежедневно переосмысливать свое собственное понимание «наилучшей практики» и шаблонов хорошо структурированного кода. В Node.js прямо сейчас течет огромная энергия идей, и работа в ней подвергает вас всему этому мышлению - великому умственному поднятию тяжестей.

Node.js в производстве определенно возможен, но далеко от «под ключ» развертывания, казалось бы, обещанного документацией. С Node.js v0.6.x «кластер» был интегрирован в платформу, предоставляя один из основных строительных блоков, но мой сценарий «production.js» все еще ~ 150 строк логики для обработки таких вещей, как создание журнала каталог, утилизация мертвых рабочих и т. д. Для «серьезной» производственной службы вам также необходимо быть готовым регулировать входящие соединения и делать все то, что Apache делает для PHP . Чтобы быть справедливым, Рубин на Rails имеет эту точную проблему. Это решается с помощью двух дополнительных механизмов: 1) Установка Ruby на Rails / Node.Apache / Lighttd ). Веб-сервер может эффективно обслуживать статический контент, осуществлять доступ к ведению журналов, перезаписывать URL-адреса, прерывать SSL , применять правила доступа и управлять несколькими вспомогательными службами. Для запросов, которые попадают в реальную службу узла, веб-сервер передает запрос через. 2) Использование фреймворка, такого как Unicorn, который будет управлять рабочими процессами, периодически их перерабатывать и т. Д. Мне еще предстоит найти обслуживающую фреймворк Node.js, который кажется полностью запеченным; он может существовать, но я еще не нашел его и до сих пор использую ~ 150 строк в моем ручном свернутом файле «production.js».

При чтении таких фреймворков, как Express, создается впечатление, что стандартная практика состоит в том, чтобы просто обслуживать все через один сервис Node.js "на все руки" ... "app.use (express.static (__ dirname + '/ public'))" , Для менее загруженных сервисов и разработки это, вероятно, хорошо. Но как только вы попытаетесь увеличить нагрузку на свой сервис и запустить его в режиме 24/7, вы быстро обнаружите мотивы, побуждающие большие сайты получать хорошо запеченный и надежный C-код, такой как Nginx, выходящий на их сайт и обрабатывающий все запросов статического содержимого (... пока вы не настроите CDN , например Amazon CloudFront )). Для несколько юмористического и откровенно негативного взгляда на это, посмотрите на этого парня .

Node.js также находит все больше и больше необслуживаемых применений. Даже если вы используете что-то другое для обслуживания веб-контента, вы все равно можете использовать Node.js в качестве инструмента сборки, используя модули npm для организации вашего кода, Browserify для сшивания его в единый ресурс и uglify-js для минимизации его для развертывания. , Для работы с Интернетом JavaScript является идеальным соответствием импеданса и часто делает его наиболее простым способом атаки. Например, если вы хотите разбираться с кучей полезных нагрузок ответов JSON , вы должны использовать мой модуль подчеркивания-CLI , служебный пояс структурированных данных.

За и против:

  • Pro: Для серверного человека написание JavaScript на бэкэнде было «наркотиком шлюза» для изучения современных шаблонов пользовательского интерфейса. Я больше не боюсь писать клиентский код.
  • Pro: имеет тенденцию поощрять правильную проверку ошибок (ошибка возвращается практически всеми обратными вызовами, из-за чего программист вынужден ее обрабатывать; также async.js и другие библиотеки обрабатывают парадигму «сбой, если любая из этих подзадач» намного лучше, чем типичный синхронный код) )
  • Pro: Некоторые интересные и обычно сложные задачи становятся тривиальными - например, получение статуса для выполняемых задач, общение между работниками или совместное использование состояния кэша.
  • Pro: Огромное сообщество и множество отличных библиотек, основанных на надежном менеджере пакетов (npm)
  • Против: JavaScript не имеет стандартной библиотеки. Вы настолько привыкли импортировать функциональность, что это кажется странным, когда вы используете JSON.parse или какой-то другой встроенный метод, который не требует добавления модуля npm. Это означает, что существует пять версий всего. Даже модули, включенные в «ядро» Node.js, имеют еще пять вариантов, если вы недовольны реализацией по умолчанию. Это приводит к быстрой эволюции, но также и некоторой путанице.

По сравнению с простой моделью «один процесс на запрос» ( LAMP ):

  • Pro: Масштабируется до тысяч активных соединений. Очень быстро и очень эффективно. Для веб-флота это может означать сокращение требуемого количества блоков в 10 раз по сравнению с PHP или Ruby.
  • Pro: Написание параллельных шаблонов легко. Представьте, что вам нужно получить три (или N) больших двоичных объекта из Memcached . Сделайте это в PHP ... вы только что написали код, извлекающий первый BLOB-объект, затем второй, а затем третий? Вау, это медленно. Существует специальный модуль PECL, чтобы исправить эту конкретную проблему для Memcached, но что, если вы хотите извлечь некоторые данные Memcached параллельно с запросом вашей базы данных? В Node.js, потому что парадигма асинхронная, веб-запрос делает несколько вещей параллельно, это очень естественно.
  • Против: Асинхронный код принципиально сложнее, чем синхронный код, и предварительная кривая обучения может оказаться сложной для разработчиков без четкого понимания того, что на самом деле означает параллельное выполнение. Тем не менее, это гораздо проще, чем писать многопоточный код с блокировкой.
  • Con: Если запрос с интенсивными вычислениями выполняется, например, в течение 100 мс, он остановит обработку других запросов, которые обрабатываются в том же процессе Node.js ... AKA, кооперативная многозадачность . Это может быть смягчено с помощью шаблона Web Workers (выделение подпроцесса для решения дорогостоящей задачи). В качестве альтернативы, вы можете использовать большое количество рабочих Node.js и позволить каждому из них обрабатывать один запрос одновременно (все еще довольно эффективно, потому что нет повторного использования процесса).
  • Против: Запуск производственной системы НАМНОГО сложнее, чем модель CGI, такая как Apache + PHP, Perl , Ruby и т. Д. Необработанные исключения приведут к останову всего процесса, что потребует логики для перезапуска сбойных рабочих (см. Кластер ). Модули с ошибочным нативным кодом могут привести к аварийному завершению процесса. Всякий раз, когда работник умирает, любые запросы, которые он обрабатывал, отбрасываются, поэтому один ошибочный API может легко ухудшить службу для других связанных API.

По сравнению с написанием «реального» сервиса в Java / C # / C (C? Действительно?)

  • Pro: Выполнение асинхронного в Node.js проще, чем обеспечение безопасности потоков где-либо еще и, возможно, обеспечивает большую выгоду. Node.js - безусловно наименее болезненная асинхронная парадигма, в которой я когда-либо работал. С хорошими библиотеками это лишь немного сложнее, чем писать синхронный код.
  • Pro: Нет ошибок многопоточности / блокировки. Правда, вы заранее инвестируете в написание более подробного кода, который выражает правильный асинхронный рабочий процесс без операций блокировки. И вам нужно написать несколько тестов и заставить их работать (это язык сценариев, а имена переменных с толстыми аппликатурами перехватываются только во время модульных тестов). НО, как только вы заставите его работать, площадь поверхности для heisenbugs - странные проблемы, которые проявляются только один раз за миллион прогонов - эта площадь поверхности просто намного ниже. Налоги на написание кода Node.js сильно загружены в фазе кодирования. Тогда вы, как правило, получаете стабильный код.
  • Pro: JavaScript намного легче для выражения функциональности. Трудно доказать это словами, но JSON , динамическая типизация, лямбда-нотация, наследование прототипов, легковесные модули, что угодно ... просто требуется меньше кода, чтобы выразить те же идеи.
  • Con: Может быть, вам действительно очень нравятся сервисы кодирования в Java?

Еще один взгляд на JavaScript и Node.js можно найти в блоге « От Java до Node.js» , где рассказывается о впечатлениях и опыте Java-разработчика по изучению Node.js.


Модули При рассмотрении узла, имейте в виду, что ваш выбор библиотек JavaScript определит ваш опыт. Большинство людей используют как минимум два, асинхронный помощник по шаблонам (Step, Futures, Async) и модуль сахара JavaScript ( Underscore.js ).

Помощник / JavaScript Сахар:

  • Underscore.js - используйте это. Просто сделай это. Это делает ваш код красивым и читаемым с такими вещами, как _.isString () и _.isArray (). Я не совсем уверен, как вы могли бы написать безопасный код в противном случае. Кроме того, для расширенной командной строки fu, проверьте мой собственный Underscore-CLI .

Модули асинхронной структуры:

  • Шаг - очень элегантный способ выразить комбинации последовательных и параллельных действий. Мои личные рекомендации. Смотрите мой пост о том, как выглядит код Step.
  • Фьючерсы - гораздо более гибкий (действительно ли это хорошая вещь) способ выразить порядок через требования. Может выражать такие вещи, как «начать a, b, c параллельно. Когда A и B закончат, начните AB. Когда A и C закончат, запустите AC». Такая гибкость требует большей осторожности, чтобы избежать ошибок в вашем рабочем процессе (например, никогда не вызывать обратный вызов или вызывать его несколько раз). См. Сообщение Рейноса об использовании фьючерсов (этот пост заставил меня "получить" фьючерсы).
  • Async - более традиционная библиотека с одним методом для каждого шаблона. Я начал с этого до моего религиозного перехода к шагу и последующего осознания того, что все шаблоны в асинхронности могут быть выражены в шаге с помощью одной более читаемой парадигмы.
  • TameJS - написанный OKCupid, это прекомпилятор, который добавляет новый примитив языка «await» для элегантного написания последовательных и параллельных рабочих процессов. Шаблон выглядит потрясающе, но требует предварительной компиляции. Я все еще решаюсь об этом.
  • StreamlineJS - конкурент TameJS. Я склоняюсь к Тейму, но ты можешь решить сам.

Или чтобы прочитать все об асинхронных библиотеках, посмотрите это интервью с авторами.

Веб-фреймворк:

  • Express Great Ruby on Rails-esk Framework для организации веб-сайтов. Он использует JADE в качестве движка шаблонов XML / HTML, что делает построение HTML гораздо менее болезненным, даже почти элегантным.
  • jQuery Хотя технически не является модулем узла, jQuery быстро становится стандартом де-факто для пользовательского интерфейса на стороне клиента. jQuery предоставляет CSS-подобные селекторы для «запроса» на наборы элементов DOM, с которыми затем можно работать (задавать обработчики, свойства, стили и т. д.). В том же духе, CSS-фреймворк Bootstrap в Twitter , Backbone.js для шаблона MVC и Browserify.js для сшивания всех ваших файлов JavaScript в один файл. Все эти модули становятся стандартами де-факто, поэтому вы должны хотя бы проверить их, если не слышали о них.

Тестирование:

  • JSHint - должен использовать; Сначала я этим не пользовался, что сейчас кажется непостижимым. JSLint добавляет кучу базовых проверок, которые вы получаете с помощью скомпилированного языка, такого как Java. Несоответствующие скобки, необъявленные переменные, шрифты разных форм и размеров. Вы также можете включить различные формы того, что я называю «анальным режимом», когда вы проверяете стиль пробелов и тому подобное, что нормально, если это ваша чашка чая - но реальная ценность заключается в получении мгновенной обратной связи о точном номере строки, где Вы забыли закрывающее ")" ... без необходимости запуска кода и попадания в оскорбительную строку. «JSHint» является более настраиваемым вариантом Douglas Крокфорд «s JSLint .
  • Мокко конкурент к обетам, которые я начинаю отдавать предпочтение. Обе структуры достаточно хорошо справляются с основами, но сложные шаблоны легче выразить в Mocha.
  • Vows Vows действительно довольно элегантно. И он выводит прекрасный отчет (--spec), показывающий, какие тестовые примеры пройдены / не пройдены. Потратьте 30 минут на его изучение, и вы сможете создавать базовые тесты для своих модулей с минимальными усилиями.
  • Zombie - Безголовое тестирование HTML и JavaScript с использованием JSDom в качестве виртуального «браузера». Очень мощный материал. Объедините его с Replay, чтобы получить молниеносные детерминированные тесты кода в браузере.
  • Комментарий о том, как «думать о» тестировании:
    • Тестирование не является обязательным. В динамическом языке, таком как JavaScript, статических проверок очень мало. Например, передача двух параметров методу, который ожидает 4, не сломается, пока код не будет выполнен. Довольно низкая планка для создания ошибок в JavaScript. Базовые тесты необходимы для восполнения пробела в проверке скомпилированных языков
    • Забудьте проверку, просто сделайте ваш код выполненным. Для каждого метода мой первый случай проверки - «ничего не ломается», и именно этот случай срабатывает чаще всего. Доказательство того, что ваш код выполняется без сбоев, улавливает 80% ошибок и сделает так много, чтобы повысить уверенность в коде, и вы вернетесь назад и добавите нюансы проверки, которые вы пропустили.
    • Начните с малого и разбейте инерционный барьер. Мы все ленивы и тратят время, и тестирование легко воспринимать как «дополнительную работу». Так что начните с малого. Напишите контрольный пример 0 - загрузите ваш модуль и сообщите об успехе. Если вы заставляете себя делать именно это, то инерционный барьер для тестирования преодолевается. Это <30 минут, чтобы сделать это в первый раз, включая чтение документации. Теперь напишите тестовый пример 1 - вызовите один из ваших методов и убедитесь, что «ничего не ломается», то есть вы не получили ошибку назад. Тестовый пример 1 займет у вас менее одной минуты. С исчезновением инерции становится легко постепенно увеличивать охват тестами.
    • Теперь развивайте свои тесты с помощью своего кода. Не пугайтесь того, как будет выглядеть «правильный» сквозной тест с фиктивными серверами и всем этим. Код начинается с простого и развивается для обработки новых случаев; тесты тоже должны. Когда вы добавляете новые случаи и новую сложность в свой код, добавляйте контрольные примеры для реализации нового кода. По мере обнаружения ошибок добавляйте проверки и / или новые случаи, чтобы покрыть некорректный код. Когда вы отлаживаете и теряете доверие к коду, вернитесь и добавьте тесты, чтобы доказать, что он делает то, что вы думаете. Захватите строки данных примера (из других сервисов, которые вы вызываете, веб-сайты, которые вы просматриваете, и т. Д.) И передайте их в свой код анализа. Здесь есть несколько случаев, улучшенная проверка, и вы получите очень надежный код.

Также ознакомьтесь с официальным списком рекомендуемых модулей Node.js. Тем не менее, GitHub's Node Modules Wiki является гораздо более полным и хорошим ресурсом.


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

Node.js является EVENT ОСНОВАНИЯ и ASYNCHRONOUS / неблокируемому, События, такие как входящее HTTP-соединение, запускают функцию JavaScript, которая выполняет небольшую работу и запускает другие асинхронные задачи, такие как подключение к базе данных или получение контента с другого сервера. После запуска этих задач функция события завершается, и Node.js возвращается в спящий режим. Как только происходит что-то еще, например, когда устанавливается соединение с базой данных или внешний сервер отвечает содержимым, функции обратного вызова запускаются, и выполняется больше кода JavaScript, что может привести к запуску еще более асинхронных задач (например, запроса к базе данных). Таким образом, Node.js успешно чередует действия для нескольких параллельных рабочих процессов, выполняя любые операции, разблокированные в любой момент времени. Вот почему Node.js отлично справляется с управлением тысячами одновременных подключений.

Почему бы просто не использовать один процесс / поток на соединение, как все остальные?В Node.js новое соединение - это всего лишь очень маленькое выделение кучи. Для раскрутки нового процесса на некоторых платформах требуется значительно больше памяти, мегабайт. Но реальная стоимость - это накладные расходы, связанные с переключением контекста. Когда у вас есть 10 ^ 6 потоков ядра, ядро ​​должно проделать большую работу, чтобы выяснить, кто должен выполнять следующее. Большая часть работы была посвящена созданию планировщика O (1) для Linux, но, в конце концов, гораздо эффективнее иметь один управляемый событиями процесс, чем 10 ^ 6 процессов, конкурирующих за время процессора. Кроме того, в условиях перегрузки многопроцессорная модель ведет себя очень плохо, из-за чего не хватает критически важных служб администрирования и управления, особенно SSHD (это означает, что вы даже не можете войти в окно, чтобы выяснить, насколько он на самом деле ввернут).

Node.js ЕДИНСТВЕННАЯ РЕЗЬБА и БЕСПЛАТНО . Node.js, как очень обдуманный выбор дизайна, имеет только один поток на процесс. Из-за этого для нескольких потоков принципиально невозможно получить доступ к данным одновременно. Таким образом, замки не нужны. Нити тяжелые. Действительно очень сложно. Если вы в это не верите, значит, вы не сделали достаточно многопоточного программирования. Правильно установить блокировку сложно, и это приводит к ошибкам, которые действительно трудно отследить. Устранение блокировок и многопоточности делает один из самых отвратительных классов ошибок просто исчезающим. Это может быть единственным большим преимуществом узла.

Но как мне воспользоваться преимуществами моего 16-ядерного блока?

Два пути:

  1. Для больших сложных вычислительных задач, таких как кодирование изображений, Node.js может запускать дочерние процессы или отправлять сообщения дополнительным рабочим процессам. В этом проекте у вас был бы один поток, управляющий потоком событий, а N процессов, выполняющих сложные вычислительные задачи и пережевывающих остальные 15 процессоров.
  2. Для масштабирования пропускной способности на веб-сервисе вы должны запустить несколько серверов Node.js на одном компьютере, по одному на ядро, используя кластер (В случае Node.js v0.6.x, официальный модуль «cluster», связанный здесь, заменяет версию learnboost, которая имеет другой API). Эти локальные серверы Node.js могут затем конкурировать в сокете, чтобы принимать новые соединения, балансируя нагрузку между ними. Как только соединение принято, оно становится тесно связанным с одним из этих общих процессов. В теории это звучит плохо, но на практике это работает довольно хорошо и позволяет избежать головной боли при написании поточно-ориентированного кода. Кроме того, это означает, что Node.js получает отличную привязку к кэшу процессора, более эффективно используя пропускную способность памяти.

Node.js позволяет вам делать действительно мощные вещи, не потревожив. Предположим, у вас есть программа Node.js, которая выполняет различные задачи, прослушивает команды на TCP- порту, кодирует некоторые изображения, что угодно. С помощью пяти строк кода вы можете добавить портал HTTP на основе веб-управления, который показывает текущее состояние активных задач. Это легко сделать:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");

Теперь вы можете нажать на URL и проверить состояние вашего запущенного процесса. Добавьте несколько кнопок, и у вас появится «портал управления». Если у вас запущен скрипт Perl / Python / Ruby, просто «добавить портал управления» не совсем просто.

Но разве JavaScript не медленный / плохой / злой / порождение дьявола? У JavaScript есть некоторые странные странности, но с «хорошими частями» есть очень мощный язык, и в любом случае, JavaScript - это язык клиента (браузера). JavaScript здесь, чтобы остаться; другие языки нацелены на него как на IL, и талант мирового класса конкурирует за создание самых продвинутых движков JavaScript. Из-за роли JavaScript в браузере огромные усилия инженеров направлены на то, чтобы сделать JavaScript быстрым. V8является последним и лучшим движком javascript, по крайней мере, на этот месяц. Он поражает другие языки сценариев как эффективностью, так и стабильностью (глядя на вас, Руби). И это будет только лучше с огромными командами, работающими над проблемой в Microsoft, Google и Mozilla, конкурирующими за создание лучшего движка JavaScript (Это больше не «интерпретатор» JavaScript, поскольку все современные движки делают тонны JITкомпиляция под капотом с интерпретацией только как запасной вариант для кода, выполняемого один раз). Да, мы все хотели бы исправить некоторые странные варианты языка JavaScript, но это на самом деле не так уж и плохо. А язык настолько чертовски гибок, что вы действительно не кодируете JavaScript, вы кодируете Step или jQuery - больше, чем любой другой язык, в JavaScript библиотеки определяют опыт. Чтобы создавать веб-приложения, вам все равно нужно знать JavaScript, поэтому кодирование с ним на сервере имеет своего рода синергию с набором навыков. Это заставило меня не бояться писать код клиента.

Кроме того, если вы ДЕЙСТВИТЕЛЬНО ненавидите JavaScript, вы можете использовать синтаксический сахар, такой как CoffeeScript . Или что-нибудь еще, что создает код JavaScript, например, Google Web Toolkit (GWT).

Говоря о JavaScript, что такое «закрытие»? - Довольно причудливый способ сказать, что вы сохраняете переменные лексической области в цепочках вызовов. ;) Нравится:

var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
    database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();

Видите, как вы можете просто использовать «myData», не делая ничего неловкого, например, спрятать его в объект? И в отличие от Java, переменная "myData" не обязательно должна быть доступна только для чтения. Эта мощная языковая функция делает асинхронное программирование гораздо менее многословным и менее болезненным.

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


«Переменная« myData »не обязательно должна быть доступна только для чтения» - похоже, вы бы хотели, чтобы она оставалась неизменной большую часть времени, чтобы избежать проблем с параллелизмом, верно?
Ник

1
@ Ник - это ложь. «проблемы параллелизма» смягчаются тем фактом, что узел является однопоточным. Блокировка в узле просто не существует; это не нужно в однопоточной парадигме.
Дейв Допсон

Кластер был интегрирован в ядро ​​узла в узле 0.6 stackoverflow.com/a/8470986/212702 nodejs.org/docs/latest/api/cluster.html#cluster_cluster
Лоран Дебрикон,

1
ps, примечание - я действительно редактировал это достаточно много раз, чтобы сообщение стало "сообществом вики" (порог составляет 10 правок). Я ошибочно думал, что это какая-то честь, когда на самом деле это просто блокирует завоевание репутации от голосов. В конце концов, один из избирателей до статуса CW нажал «unvote» (надеюсь, случайно :), и я потерял репутацию ... в замешательстве, я подал meta.stackexchange.com/questions/129941/… и был обучен в каком «Сообществе» Вики "на самом деле означает. Моды были достаточно любезны, чтобы убрать статус CW. :)
Дейв Допсон

1
@John - мой комментарий по отладке абсолютно применим и к vanilla asnyc. Чтобы прервать отладку, все, что мне нужно сделать, это обернуть вызов некоторой функции в «process.nextTick (...)». Затем, когда он выдаст, моя трассировка стека начнется с process.nextTick; не очень полезно То, что я действительно хочу знать, это: «какой стек запланирован process.nextTick?» Я называю эти данные «причинно-следственными цепочками», и это напоминает мне о «selectedBy» в обработке исключений Java ... низкоуровневые броски кода, среднеуровневый код перехватывает исключение LL и выбрасывает FrameworkMethodFailedException - без 'basedBy', стек из LL код будет потерян.
Дейв Допсон,

85

V8 - это реализация JavaScript. Это позволяет вам запускать автономные приложения JavaScript (среди прочего).

Node.js - это просто библиотека, написанная для V8, которая выполняет четные операции ввода-вывода. Эту концепцию немного сложнее объяснить, и я уверен, что кто-то ответит лучше, чем я ... Суть в том, что вместо того, чтобы делать ввод или вывод и ждать, пока это произойдет, вы просто не ждите чтобы это закончилось. Например, запросите время последнего редактирования файла:

// Pseudo code
stat( 'somefile' )

Это может занять пару миллисекунд или несколько секунд. С помощью Evented I / O вы просто запускаете запрос и вместо ожидания добавляете обратный вызов, который запускается после завершения запроса:

// Pseudo code
stat( 'somefile', function( result ) {
  // Use the result here
} );
// ...more code here

Это очень похоже на код JavaScript в браузере (например, с функциональностью в стиле Ajax ).

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


4
Каким образом реализован четный ввод-вывод без использования блокировок, потоков, процессов, замыканий? И у меня есть ощущение, что концепции очень похожи на концепции функционального программирования и Erlang.
Джефф

1
Насколько я знаю, это реализовано как простой цикл обработки событий. v8 уже имеет функциональность callback / etc, как и любая реализация javascript.
rfunduk

2
Цикл событий ввода-вывода в node.js означает, что в любой данный момент времени выполняется не более одной вещи. Я вижу два существенных преимущества: нет никаких накладных расходов на переключение потоков, поэтому node.js работает очень быстро, и, во-вторых, многие типичные ошибки параллелизма, которые, как известно, Java не возможны.
nalply

1
«Каким образом реализован четный ввод-вывод без использования ... замыканий?» JavaScript поддерживает замыкания, и они все время используются в node.js (анонимные функции и пример здесь).
Panzi

@panzi: не заметил, что Джеффри включил замыкания в свой список вещей. node.js реализован «без». Очевидно, что каждая функция в javascript - это замыкание по объему :)
rfunduk

35

Node.js - это инструмент командной строки с открытым исходным кодом, созданный для кода JavaScript на стороне сервера. Вы можете скачать tarball , скомпилировать и установить исходный код. Это позволяет вам запускать программы JavaScript.

JavaScript выполняется V8 , движком JavaScript, разработанным Google, который используется в браузере Chrome . Он использует JavaScript API для доступа к сети и файловой системе.

Он популярен благодаря своей производительности и способности выполнять параллельные операции.

Понимание node.js - лучшее объяснение для node.js, которое я нашел до сих пор.

Ниже приведены несколько хороших статей на эту тему.


13

Замыкания - это способ выполнить код в контексте, в котором он был создан.

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

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

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


8

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

Я настоятельно рекомендую вам посмотреть и прочитать эти статьи:

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

С Node.js это так же просто, как делать это в клиентском JavaScript-коде. Получите ваш DOM-узел и примените к нему свой CSS-класс. Получите ваш DOM-узел и innerHTML-контент (для этого вам понадобится дополнительный код JavaScript. Прочтите статью, чтобы узнать больше).

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


7

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

Вот резюме:

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

Node.js управляется событиями, но большинство веб-серверов основаны на потоках. Йорк объясняет, как работает Node.js:

  • Вы используете свой веб-браузер, чтобы сделать запрос для "/about.html" на веб-сервере Node.js.

  • Сервер Node.js принимает ваш запрос и вызывает функцию для извлечения этого файла с диска.

  • Пока сервер Node.js ожидает получения файла, он обслуживает следующий веб-запрос.

  • Когда файл извлекается, в очередь серверов Node.js вставляется функция обратного вызова.

  • Сервер Node.js выполняет эту функцию, которая в этом случае отображает страницу «/about.html» и отправляет ее обратно в веб-браузер ».


6

Ну я так понимаю

  • Цель Node - предоставить простой способ создания масштабируемых сетевых программ.
  • По своему дизайну Node похож на такие системы как Ruby's Event Machine или Python's Twisted.
  • Evented I / O для V8 JavaScript.

Для меня это означает, что вы были правы во всех трех предположениях. Библиотека, безусловно, выглядит многообещающе!


1
Много раз я нахожу о странице довольно расплывчато.
Джефф

6

Кроме того, не забудьте упомянуть, что Google V8 очень быстрый. Он на самом деле преобразует код JavaScript в машинный код с соответствующей производительностью скомпилированного двоичного файла. Таким образом, наряду со всеми другими замечательными вещами, это безумно быстро.


3

В: Модель программирования основана на событиях, особенно в том, как она обрабатывает ввод / вывод .

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

Q: Он использует JavaScript и парсер V8.

да

Q: Его можно легко использовать для создания параллельных серверных приложений.

Да, хотя вам нужно было бы написать много кода JavaScript. Возможно, было бы лучше взглянуть на платформу, такую ​​как http://www.easynodejs.com/, которая поставляется с полной онлайн-документацией и примером приложения.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.