Как вы делитесь EventEmitter в node.js?

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

Спасибо!


person fancy    schedule 18.05.2012    source источник


Ответы (3)


Вы можете передавать аргументы для требуемых вызовов следующим образом:

var myModule = require('myModule')(Events)

А потом в моем модуле

module.exports = function(Events) {
    // Set up Event listeners here
}

С учетом сказанного, если вы хотите поделиться эмиттером событий, создайте объект эмиттера, а затем перейдите к вашему файлу/модулю/скрипту в вызове require.

Обновлять:

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

person srquinn    schedule 18.05.2012
comment
Как вы контролируете поток этих запросов? Скажем, нужны 4 файла. Модуль просто выставляет переменную = new EventEmitter()? И он будет создан до того, как кто-либо сделает что-либо с требованиями? - person fancy; 19.05.2012
comment
Я только что реализовал шаблон, который описал, и, похоже, он работает довольно хорошо. У меня есть модуль с именем emitters, который предоставляет файл exports.variable = new EventEmitter(). Оба файла require этого emitters модуля, и могут передавать события через variable. - person fancy; 19.05.2012
comment
Вы также можете рассмотреть возможность сохранения модуля верхнего уровня, который создает объект Emitter, а затем передавать этот объект любым дочерним модулям, которым необходимо прослушивать глобальные события, если я осмелюсь использовать это слово. - person srquinn; 19.05.2012
comment
Я предположил, что описанный мной шаблон будет создавать экземпляр нового EventEmitter каждый раз, когда он мне потребуется, но, похоже, он не ведет себя так, как это действительно приятно. Надеюсь, я ничего не упускаю. - person fancy; 19.05.2012
comment
@fancy Node.js кэширует модули, поэтому код в них фактически будет запускаться только в первый раз, когда вам понадобится этот модуль. - person Aaron Dufour; 11.09.2013

@srquinn верен, вы должны использовать общий экземпляр:

eventBus.js:

const EventEmitter = require('events');
const emitter = new EventEmitter();

emitter.on('uncaughtException', function (err) {
    console.error(err);
});

module.exports = emitter;

Использование:

var bus = require('../path/to/eventBus');

// Register event listener
bus.on('eventName', function () {
    console.log('triggered!');
});

// Trigger the event somewhere else
bus.emit('eventName');
person Omer Leshem    schedule 25.09.2016
comment
проголосовал, но не работает, если у меня есть файл pub.js и другой sub.js, где мне требуется eventbus.js, и я пытаюсь запустить из одного и получить событие из другого - person PirateApp; 13.04.2019

Почему бы не использовать EventEmitter глобального объекта процесса?

process.on('customEvent', function(data) {
  ...
});

process.emit('customEvent', data);

За: вы можете отключить или полностью удалить модуль (например, трекер), не удаляя весь ваш код отслеживания в ваших маршрутах. Я делаю именно это для node-trackable.

Минусы: сейчас нет, но, пожалуйста, дайте мне знать, если увидите здесь подвох ;-)

person Sascha Reuter    schedule 07.02.2013
comment
возможные / возможные конфликты в именах событий, кажется, безопаснее быть явным. - person Louis; 22.03.2013
comment
Против: события будут привязаны к одному процессу, что предотвращает горизонтальное масштабирование с помощью кластерного модуля или других методов. - person srquinn; 26.03.2014
comment
@jibsales Как бы вы распределили генератор событий между работниками в кластере? Кластеры совместно используют серверные порты, но я не уверен, могут ли они легко совместно использовать объекты javascript. - person wheresrhys; 06.11.2014
comment
@Louis, это будет проблемой для любого общего эмиттера событий, если вы не будете осторожны с именами - person wheresrhys; 06.11.2014
comment
@Sascha_Reuter Вариантом этого может быть назначение собственного источника событий в качестве свойства процесса. - person wheresrhys; 06.11.2014
comment
@wheresrhys Использование какой-либо формы шины сообщений или подождите, пока модуль Domain в ядре узла немного созреет. - person srquinn; 07.11.2014