Node.js события, краткая заметка

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

В Node.js широко использованы события, для бд, для http, стримов, практически нет раздела, где их нельзя применить.

В работе я применяю события, намного чаще калбеков. И вот, впервые, заметил, большинство учебников описывают создание EventEmitter через конструктор.

Приведу пример этого:

var EventEmitter				= require( 'events').EventEmitter
    ,inherits					= require( 'util').inherits;

var function test(){
    var self = this;
    ....
    ............... self.emit( 'done', data);
    ....
}
inherits( test, EventEmitter);
.....

Вызов:

new test().once( 'done', callback);

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

var EventEmitter				= require( 'events').EventEmitter

var function test(){
    var emiter = new EventEmitter;
    ....
    ...............emiter.emit( 'done', data);
    ....
    return emiter;
}

Вызов:

test().once( 'done', callback);

Конечно, это ни сколько не уменьшило права на жизнь, предыдущего способа, это просто — другой способ.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Посоветуйте литературку по Nodejs(в процессе работы еще необходимы будут знания nodejs+mysql+nginx). И администрирование серверов под debian.
Так же ищу менторов по данной теме :)
Спасибо за ответы

Могу познакомить вас со своим админом, он как раз недавно разбирал связку nodejs+nginx под debian.

Что до nodejs+mysql, просто не делайте так, без явной необходимости. Лучше почитайте о mongodb.

Сам я учился с разных источников.
Как основу Node.js, рекомендую скринкасты от Ильи Кантора
www.youtube.com/watch?v=UzaSErq29Ak
Они немного устарели по версиям модулей, что там упоминают, но все еще актуальны.

Что до nodejs+mysql, просто не делайте так, без явной необходимости.
А что не так в связке ноды и мускула?

Да все так, если вам достаточно этого.

Кстати, поковыряйте стандартные модули ноды (fs например). Почти нигде там модель событий не используется. Используются колбеки. И то на все эти модули уже написаны promised обертки, потому что желания писать спагетти код с коллбеками нет не только лишь у всех.

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

httpServer, или socket-io сервер, хотя и имеют базовый API основаный на событиях, поверх них ложится Express или какой-то RPC сервер с нормальным API без событий.

Про модули БД, которые генерируют события — может кто-то ради лулзов такой и написал, но все мейнстримовые модули будут работать с колбеками + как обычно обертки предоставляющие промисы.

Однако Артем, ваше мнения тоже имеет право на жизнь.

BTW, обернуть колбечное в промис, чаще всего, можно и самому, я пока не видел (насколько помню) проблем.

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

Мы говорим об одном и том же? о серверной разработке?
Ведь если на фронте, события в большинстве ограничены, то серверный EventEmiter это несколько другое.

Мы говорим об одном и том же?
хз
о серверной разработке?
nodejs это пока что серверная разработка и немного десктопной, но это роли не играет.
Ведь если на фронте, события в большинстве ограничены, то серверный EventEmiter это несколько другое.
поясните, какой именно смысл вы пытаетесь вложить в эту фразу.

Пока что выглядит так, что вас по какой-то причине зациклило на EventEmitter (почему, например, не на ChildProcess? Тоже прикольный и полезный класс)

Потому что тема заметки о EventEmitter, не о ChildProcess. Говори мы о ChildProcess, я говорил бы о ChildProcess.

Две мысли после прочтения:
* ну и?
* во-втором случае нужно было всунуть промисы

Конечно, подход promise можно использовать и в Node.js, мы говорим как раз об этом с Michael P
Присоединитесь к нашему обсуждению
dou.ua/...orums/topic/12890/#657383

Чего б не
test().then(function(result){do something}) ?
Промисы ж уже и в javascript всунули ;)

Это уже третий способ. По сути, он не отличается ничем от предложного выше.

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

Проминсы не имеют особых преимуществ, в контексте Node.js.

его возможности больше.
так поведайте же мне и другим о них. А слово «библиотека» в следующей строчке, совершенно точно характеризует async, который таки не попал в сам язык, в отличии от промисов.
так поведайте же мне и другим о них.
Прошу — github.com/caolan/async


Что до остального, Node.js — низкоуровневый веб сервер, для него нормально http сервер модулем или WebSocets модулем. Создатель ноды — Райан Дал, в своих заявлениях говорит
давайте будем придерживаться минимализма и создадим лишь фундамент

Давайте пойдем далее, посмотрим на замечательную библиотеку jQuery или фреймворк Backbone.js. Почему их не встроили в язык? ответ говорит нам PHP, с его ядре, три библиотеки для работы с графикой, вместо одной.

Сегодня, этот модуль в тренде, завтра придумают другой, еще лучше.

Ок, я понял свою ошибку и привожу цитату побольше:

Для большинства EventEmiter будет предпочтительней, его возможности больше.
Вот об этом расскажите.

А про минимализм — чем не минимализм использовать встроенные в язык средства?

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


var db = require( ’libs/db’)
mongoose = require( ’mongoose’)
,util = require( ’util’);
Первый модуль — это модуль самого проекта, второй — модуль из npm, третий — встроенный модуль ноды. Как видите, у них единый синтаксис, они одинаково обрабатываются, они одинаково используют системные ресурсы.


EventEmiter, Вот об этом расскажите
Если вы использовали Promise раньше, бесспорно, этот инструмент вам ближе. Но активно работая с Node.js, вы не могли, не познакомится с объектом событий EventEmiter.

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

EventEmiter делает события, спасибо кеп, сказал классик. Классик был прав, но не копал глубже.
Давайте представим некий компонент, реализующий блоги.


blog.on( ’new_post’, callback);
Ничего нового? все тот же then, не совсем.
then будет написан там же, где этот блог, а слушателей события я могу вешать из любого места, в любом количестве, эти события могут быть разные, и это имеет некоторые механизмы, для борьбы с утечками памяти. В контексте Node.js, это важно.

если бы мне были нужны слушатели «из любого места», я бы сделал pub/sub (в том числе и EventEmitterом, например)
Но в одном-то месте цепочку строить?

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

я бы сделал pub/sub

а как вы сделаете это?


var emiter = new require( ’events’).EventEmitter

module.exports = function(){
....
return emiter;
}



у меня данных о производительнсти конечно нет, но что-то подсказывает, что чем-то мы жертвуем.
Например задержка при первичном поиске модуля, модуль может быть не в первом списке а втором. Но время запуска веб приложения наименьшие что волнует разработчика.

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

Нода понимает подключенные модули на C++, в этом тоже, не достигнуть преимущества.

Конкретно github.com/caolan/async на чистом js, если я не ошибаюсь.
Первого вопроса не понял, но pub/sub, вроде, как раз предполагает, что он доступен из «разных мест»

Да, async на js.
В первом вопросе, я хотел увидеть как вы реализуете pub/sub.

Ну сделал бы модуль, который создает и экспортит синглтон c eventEmitter и методами, потом бы его импортил и использовал, наверно. Хотя еще никогда не возникало потребности во «внутреннем» pubsub, разве что во внешнем...

К этому и веду, все сошлось на EventEmiter

а приведите пример, практический, когда оно надо (реализовывать такой глобальный pubsub, но недостаточно глобальный, чтобы вынести его наружу процесса)

что вы подразумеваете под

вынести его наружу процесса

Есть достаточно много модулей, которые выбрасывают события наружу.

Первый модуль — это модуль самого проекта, второй — модуль из npm, третий — встроенный модуль ноды. Как видите, у них единый синтаксис, они одинаково обрабатываются, они одинаково используют системные ресурсы.

Разница будет, если модуль — это С++ аддон. И если вы взглянете на исходники ноды, то увидете, что там 25% — это именно С и С++.

Возможно, я не заглядывал так далеко, так как не владею C или C++, но будет ли разница для модуля, уже загруженного в оперативную память?

Зависит от самого модуля. Можно и на плюсах написать так, что на JS будет быстрее(и, по заверениям авторов Ноды, это сделать легко).
Но смысл С++ аддонов как раз в том, чтобы предоставить повышенную производительность и более оптимальное использование памяти _там, где это нужно_.

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

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

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

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

насчет собственно поста. в ноде юзать утилиту для наследование плохой тон, когда есть Object.create. дальше наследовать от EventEmiter не хорошо с точки зрения дизайна системы. намного лучше EventEmiter добавлять как примесь.

возможностей у него на много больше чем у промисов
Откройте мне уже этот секрет :)

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

Ну если вы про Control Flow, все эти whilst, то, насколько я помню, есть в промисах (сторонних), насчет встроенных в язык, уверен, что нет :)

*отредактировано* не туда написал =)

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

Что до инхеритс, именно этот способ, пожалуй в каждом втором мануале по ноде.

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

Что до инхеритс, именно этот способ, пожалуй в каждом втором мануале по ноде.
мануалы разные люди пишут, и они имеют свойства наглядности

Понял вашу мысль, соглашусь.

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

Підписатись на коментарі