0

I want one or more file to emit event(s) and multiple other files to listen to it. They should share the same instance. This what I've tried to do

To test the code, I have 3 files

  1. eventEmitter.js - this creates a new EventEmitter object and exports it
  2. eventGenerator.js - this emits events using the emitEvent.js
  3. listenEvent.js - this listens to events using emitEvent.js

I'm using require in eventGenerator.js and listenEvent.js and exporting the object in eventEmitter.js, I'm hoping it follows a singleton pattern and they share the same instance.

Here are some resources I checked out, before posting this. Disclaimer: I have adapted some design/code from these files for testing.

Here are the three files.

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');
}); 

Issues

  • listenEvent.js does not receive the event and exits immediately.
  • If I emit and listen on the same file, it works fine.
  • It looks like listenEvent.js and eventGenerator.js have different instances of the em object. Why is this happening?

Am I missing something trivial here?

Thanks in advance!

Manas Khandelwal
  • 3,790
  • 2
  • 11
  • 24
am3
  • 681
  • 2
  • 12
  • 30

2 Answers2

1

Answering my own question - I was able to get it working with a different approach - using the global variable. I'm still unable to figure out the issue with the other approach. Here are the 3 files

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');
});
am3
  • 681
  • 2
  • 12
  • 30
0

I have faced the same problem. It seems an incident with parsing your JavaScript files. TBH I do not know how technically correct it is.

So when you are running your code, your EventEmitter function along with your custom emitters and listeners need to be parsed by the Node engine. If it is not parsed by the time it should be emitted, node shall never know any such code exists.

In my case, the emitter was in the normal code flow. But the listener was in a separate file which was never imported (or you can say used). So Node never parsed it and even though the event was fired, it was not being listened upon.

To solve this problem, I used subscription methodology, to ensure the listener is parsed before being emitted the very first time.

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

So before emitting event if the method in listener is called, it is parsed and is known to Node engine.

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

This example does not show the ideal way to do it. However, should give you the idea of what can be done to achieve it.

Kaustav Sarkar
  • 181
  • 2
  • 8