Node.js: Function vs EventEmitter

In a topic about EventEmitter , someone said that in the following example, there is no need to use events. it is meaningless:

const events = require("events")
const eventEmitter = new events.EventEmitter()


eventEmitter.on("say_hi", () => {console.log("sa")})
eventEmitter.emit("say_hi")

He had said:

When you build a library or internal API, it allows other parts of your code (or people using your code) to subscribe to events without you needing to know this in advance.
For the case you used it above, it does not make sense.

But I did not understand the meaning of his sentence at all.
I did not know at all when to use the EventEmitter and when to use the Function .

In another topic, he implemented his example with both EventEmitter and Function . There was no difference in execution except that the event was assigned to an object (called student_max) and if it was to be implemented for another student, the event had to be rewritten (ie repeated) but in function all objects (all students) could Use the score method.

Can someone clearly explain by example and code when to use EventEmitter and when to use Function ?

Think of an event like a MC at a dance party. He is up on stage and grabs the mic to tell the party about something going on. He might be saying there is food or that they are going to start the team dance competition in 10 minutes.

Now, a function situation would be if this MC knew that Johnny at the party needed to get the food ready. He would say “Johnny, go get the food ready.” The MC would have to know about Johnny and that he can go get the food ready. He would “call” on Johnny to do something.

Events is if the MC just threw out the message and didn’t care if Johnny was listening or not. Maybe Johnny is listening (subscribed) or he is not. Maybe Mary is also listening and while Johnny is getting food, Mary is running to the restroom really quick. Does the MC know about Johnny or Mary in particular? Most likely not.

Events are what are commonly described as a “publisher / subscriber” mechanism. The MC is the publisher telling everyone what has happened… he doesn’t care if everyone, some of the people or none of the people are listening (they are the subscribers).

Why this guy said it is meaningless in your example is because you subscribe to an event called say_hi (the on here is saying you are subscribing) and then you immediately emit the event. In this situation you are doing both the subscribing and the emitting. Where events really work is when you are publishing the event without knowing if any other code has subscribed to it.

You might create a library or an API that is triggering events all the time and you don’t care if some other developers code is listening. You emit an event saying your code received some data. This may or may not trigger other code… you don’t care. Once you are done processing that data, you might emit another event saying you are done. Again, someone might be listening or they might not be. Again, you don’t care. Your code emits and other code (possibly written by someone else) subscribes to the events you emit. Just like how Johnny subscribed to the event that when the MC says food is about to be ready, that he needs to go get the food setup.

Hopefully that makes sense. If you remember the situation where someone is announcing something happened (emitting the event) and that zero to many others might be subscribed to the event (by using the on method) that should help keep things straight.

4 Likes

After Martyr2’s excellent breakdown, hopefully this doesn’t muddy the waters.

First of all in the following 10 minute video the tutor gives a straightforward example on how to implement an EventEmitter.

I think it might help give a better understanding.

If you follow the tutorial then one of the standouts that I was trying to pick up on earlier is that you can have numerous subscribers, even with the same name.

So going off your last link with the two examples. Instead of having a this.score method that is limited to one task as in…

this.score = function(points) {
    if (points > 90) { .... }
    ....
    console.log(`${this.name} ${points} points`);
}
...
student_lenny.score(95);

You could have numerous callbacks triggered.

function checkPoints(points) { if (points > 90) { .... } }
function updateScoreTable(points) { ... }

student_lenny.on('score', checkPoints)
student_lenny.on('score', updateScoreTable) 

student_lenny.emit('score', 95) // checks points, then updateScoreTable

I think the above is somewhat flawed, but hopefully illustrates the added flexibility.

3 Likes

Thanks for the good example.
Can I say that events act like interfaces?

No… interfaces are a bit different. They govern how two systems, entities, classes or unit of code can interact with one another. Now an interface could describe that a system has events that you can subscribe to. Back to the dance party analogy, lets say that MC tells the group that he also takes requests for songs, but you have to meet him at the MC desk and fill out a small form. This would be the MC setting out what he can do (take requests) and how you do that (by sending him some data via a form). As you fill out his form, he might also say "Hey, I also mention when songs are about to be played. You can subscribe to this event so when I announce the song (emit) you will know and can get out on the dance floor.

The keyword you will often see with interfaces is the word “contract”. A governed predetermined set of rules that both systems/classes or whatever agree to. The MC agrees to playing songs by request and you agree that you will fill out the form as requested to use that feature.

1 Like

That’s great! :rose::heart:
So can it be said that one of the most important uses of events is the SOLID principle(open/close) for implementing Clean Code?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.