Is it possible for different classes to detect 'emits' from eachother in Nodejs?

I am struggling with what seems to be a simple concept which makes me think what I am doing can't be done.

In nodejs, if class objectA.emits('hey there'), can class objectB.on('hey there') repsond with 'yo'?

Object A and B have nothing to do with eachother other than they both extend EventEmitter and are in the same nodejs app.

Sorry if this question has been asked before, I can't find it.

  1. Yes
  2. That's pretty much it.

When dealing with Observer/Publisher-Subscriber patterns (or Mediator Patterns), the point is that it really doesn't matter what type of class it is that's doing the "emitting".

Assuming that A is an emitter:

var B = { doStuff : function () { console.log("Yo!"); } };

A.addListener("someEvent", B.doStuff);
A.emit("someEvent");

If you actually want them to talk back and forth, then you need to manually subscribe them to one another...

Assuming that both A AND B are emitters:

B.doStuff = function () { this.emit("B's event", "Yo!"); };
A.doThing = function (param) { console.log(param); };

B.addListener("B's event", A.doThing);
A.addListener("A's event", B.doStuff.bind(B));

A.emit("A's event");

Alternatively, you should look into a Mediator pattern (which also "emits", but is intended to be 1 object which mediates between many objects who don't know one another, but use the same event-names and pass well-defined data-structures, like a good API should).

Assuming that Mediator is an emitter, and A, B and C aren't:

var A = {
        getData : function (request) { /* network call */ this.dataCallback(data); },
        dataCallback : function (data) { Mediator.emit("data-recieved", data); }
    },
    B = {
        display  : document.getElementById("data-display"),
        showData : function (data) { /* make DOM representation */ }
    },
    C = {
        input : document.getElementById("request-input"),
        button : document.getElementById("request-button"),
        getRequest : function () {
            var request = this.input.value;
            this.requestData(request);
            this.disableButton();
        },
        requestData : function (request) { Mediator.emit("data-request", request); },
        disableButton : function () { this.button.disabled = true; },
        enableButton  : function () { this.button.disabled = false; }
    };


    Mediator.addListener("data-request", A.getData.bind(A));
    Mediator.addListener("data-received", B.showData.bind(B));
    Mediator.addListener("data-received", C.enableButton.bind(C));

    C.button.addEventListener("click", C.getRequest.bind(C), false);

So now you've got 3 classes who know nothing about one another, each has its own special purpose, and the only expectations that they have of "one another" are that event-names and data-types are appropriate.

They all know about Mediator.
If you want Mediator to be further abstracted, then you can pass a reference to it when you're making your class:

function A (param1, param2) {
    var emitter = null;
    this.setEmitter = function (myEmitter) { emitter = myEmitter; };
    this.emit = function (evt, data) {
        if (!emitter) { return; }
        emitter.emit(evt, data);
    };
    this.subscribe = function (evt, callback) {
        if (!emitter) { return; }
        emitter.addListener(evt, callback);
    };
    /* rest of the object */
};


var a = new A();
var b = new A();


a.setEmitter(Mediator);
a.subscribe("some-evt", a.doSomething.bind(a));

b.setEmitter(Mediator);
b.subscribe("other-evt", b.doSomethingElse.bind(b));

a.emit("other-evt", { /* data */ });

a and b don't have to be the same class, here, at all.
And now they DO work in the way that you're imagining.
Both have used Dependency Injection ("Inversion of Control") to point to the same emitter (Moderator), so they're both working off of the same event-list, without even knowing it, and using their own methods to subscribe to Moderators events.