javascript - ES6: Emitting events from static methods - Stack Overflow

admin2025-04-22  0

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?

Share Improve this question asked Oct 26, 2016 at 20:45 alex-phillipsalex-phillips 8684 gold badges15 silver badges24 bronze badges 6
  • How about a singleton, then? – MaxArt Commented Oct 26, 2016 at 20:49
  • Instantiating a new instance of a class is effectively the same as creating a static object. Why not? – tcooc Commented Oct 26, 2016 at 20:49
  • @MaxArt I thought about that, but the 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
  • @alex-phillips you need to create your own proxies for static methods. 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
  • @zerkms I assume 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
 |  Show 1 more ment

2 Answers 2

Reset to default 6

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');
        });           
    }
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745284036a294280.html

最新回复(0)