Node.js: совместное использование объекта между несколькими файлами

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

Для тестирования кода у меня есть 3 файла

  1. eventEmitter.js — создает новый объект EventEmitter и экспортирует его
  2. eventGenerator.js - это генерирует события, используя emitEvent.js
  3. listenEvent.js - это слушает события, используя emitEvent.js

Я использую require в eventGenerator.js и listenEvent.js и экспортирую объект в eventEmitter.js, я надеюсь, что он следует одноэлементному шаблону, и они используют один и тот же экземпляр.

Вот некоторые ресурсы, которые я проверил, прежде чем опубликовать это. Отказ от ответственности: я адаптировал дизайн/код из этих файлов для тестирования.

Вот три файла.

eventEmitter.js

//eventEmitter.js
var events = require('events');
var em = new events.EventEmitter();

module.exports.universalEmitter = em;

eventGenerator.js

//eventGenerator.js
var eventEMitter = require('./eventEmitter.js');
var universalEmitter = eventEmitter.universalEmitter;

setInterval(function () {
  
   universalEmitter.emit('Hello');
   console.log("emitting event\n");
 
}, 3000);

listenEvent.js

//listenEvent.js
var eventEmitter = require('./eventEmitter.js');
var universalEmitter = eventEmitter.universalEmitter;

universalEmitter.on('Hello',function(){
    console.log('received hello\n');
}); 

Проблемы

  • listenEvent.js не получает событие и немедленно завершает работу.
  • Если я излучаю и слушаю один и тот же файл, все работает нормально.
  • Похоже, что listenEvent.js и eventGenerator.js имеют разные экземпляры объекта em. Почему это происходит?

Я пропустил что-то тривиальное здесь?

Заранее спасибо!


person am3    schedule 13.01.2017    source источник


Ответы (2)


Отвечая на мой собственный вопрос - я смог заставить его работать с другим подходом - с использованием глобальной переменной. Я все еще не могу понять проблему с другим подходом. Вот 3 файла

eventEmitter.js

var events = require('events');
global.universalEmitter = new events();

eventGenerator.js

setInterval(function () {

       universalEmitter.emit('Hello');
       console.log('emitting event\n');

}, 2000);

listenEvent.js

require('./emitEvent');
require('./listenEvent');

universalEmitter.on('Hello',function(){
    console.log('received hello\n');
});
person am3    schedule 14.01.2017

Я столкнулся с той же проблемой. Кажется, инцидент с разбором ваших файлов JavaScript. ТБХ Не знаю, насколько это технически правильно.

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

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

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

//eventGenerator.js
import listenEvent from '..listenEvent';
.....//SomeCode
listenEvent.register(eventEmitter) 
.....//SomeCode
setInterval(function () {
  universalEmitter.emit('Hello');
  console.log("emitting event\n");
}, 3000);

Таким образом, перед отправкой события, если вызывается метод в слушателе, он анализируется и становится известен движку Node.

//listenEvent.js
export let register = (eventEmitter) => {
     //Your listener Code
}

Этот пример не показывает идеальный способ сделать это. Тем не менее, должен дать вам представление о том, что можно сделать для ее достижения.

person Kaustav Sarkar    schedule 23.04.2019