What is the best way, or is there a best practice or workaround, to emit an event from a static method call?
Let's say I have a ES6 class that calls upload
and uploads files in a directory recursively to some endpoint and I want an event emitted after each individual file is successfully uploaded. I know I can have the class inherit EventEmitter
, but the .on
and .emit
functions don't exist without instantiating a new instance of the class. Is there any way around this?
What is the best way, or is there a best practice or workaround, to emit an event from a static method call?
Let's say I have a ES6 class that calls upload
and uploads files in a directory recursively to some endpoint and I want an event emitted after each individual file is successfully uploaded. I know I can have the class inherit EventEmitter
, but the .on
and .emit
functions don't exist without instantiating a new instance of the class. Is there any way around this?
upload
method then calls uploadFile
individually as it traverses through directories, so once inside that function it is just inside another static method. Singleton would work in some cases, and I could change my code to work, but not sure if there was a better way without making the methods non-static. @tcooc The NodeJS runtime is giving me a Class.on is not a function
error.
– alex-phillips
Commented
Oct 26, 2016 at 20:51
Class.on = (...args) => emitter.on(...args);
or Class.on = emitter.on.bind(emitter);
. Where emitter
is an instance of an EventEmitter
you need to create before your class declaration.
– zerkms
Commented
Oct 26, 2016 at 20:55
emitter
in this case would be a single instance (new EventEmitter()
) specifically for that static class? And then just bind that single instance to the static methods?
– alex-phillips
Commented
Oct 26, 2016 at 20:59
There is no way around it. If you want to call .emit()
, then you need an instance of EventEmitter
somewhere that you can call the .emit()
on. And, of course, this makes sense because your other code has to have something to call .on()
with to register listeners on.
If you don't need a separate emitter for every object, you can make just one shared emitter that you either store in some other object, in some useful scope or in module scope or you can even make the single emitter be a class static. If the emitter instance is a class static (initialized at startup), then the static methods could all reference it.
jfriend00 is right, there is no way around without creating an instance of EventEmitter, but using the Singleton pattern it is possible to implement a solution to your problem, for example:
This is the singleton "eventEmitterHandler.ts"
import {EventEmitter} from "events";
export default class EventEmitterHandler extends EventEmitter {
private static instance: EventEmitterHandler;
private constructor() {
super();
}
static getInstance() {
if (!EventEmitterHandler.instance) {
EventEmitterHandler.instance = new EventEmitterHandler();
}
return EventEmitterHandler.instance;
}
}
The class with the static method
import EventEmitterHandler from "./eventEmitterHandler";
export default class ClassA {
constructor() {}
public static staticMethod() {
EventEmitterHandler.getInstance().emit('wave');
}
}
The class with the subscription to the event
import EventEmitterHandler from "./eventEmitterHandler";
export default class ClassB {
constructor() {
EventEmitterHandler.getInstance().on('wave', () => {
console.log('constructor wave');
});
}
}