Understanding EventEmitter | Understanding Node.js Core Concepts

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey and welcome back now before we move on any further and talk about things like streams the net module the http module and so on we first have to take some time and understand a javascript object that node.js gives us and that is the event emitter object so what exactly is this event under object and what sort of problems it solves before i answer those questions let's just very quickly include the object and use it now i'm not going to do anything crazy here i'm just going to include the object and use it just to have a working program with that object so i'm going to say const event emitter equals require events like this now let's not focus on what exactly is this file is this events we're going to take a look at the source code and see what exactly it exports and what are some of the other objects that we have available so with this emitter object that i have what i could do right now is to define a class define an object and make it specify it in a way to inherit from this object now i want to use the es6 class syntax to define my object and to inherit from this object now if you don't know what classes are and what is inheritance in javascript it's completely fine i'll talk about it in a couple of minutes and give you some resources to learn about those things if you want but right now let's just focus on getting our program to function so to find my class i'm going to call it emitter which extends or inherits from this event emitter object and it's just a class so i'm just going to find an empty class this is the same if you define an object and define the prototype this object to point to the prototype of this object so let's now move on now now that i have my class emitter i'm going to create a new instance of it using the new keyword so i'm going to say const my emitter which i'm going to abbreviate it to just my e equals new emitter like this now with my object in place i could now make use of those methods that this object this event from their object gives me so i could say my e dot on foo and a function i know it's probably not going to make any sense to you but just put it with me for a second and you're going to see how this works and then i'll explain everything so here in the console.log i want to say events occurred now another important function that this event remember object gives us is the emit function so i could say my e.mit the name of the events which in this case is foo so i'm going to say foo and that's it so i defined a listener for an event and right here i am firing that event so let's go ahead and run this program i'm going to open up my terminal and i have this code inside of this app.js file so i'm going to say node app.js and here we go events occurred and actually i want to change it to an events occurred to make it sound more natural and i also missed c here there we go now this is the bare minimum that we have to understand about event emitters the on the emits methods and also the way we inherit from this event or object so let's first now discuss what exactly is this object and why do we even have it a note now i want to make a point extra clear right now and that is that this events file this source code here has nothing to do with the event loop with libya v with asynchronous code and all of that stuff that we talked about in the previous video this has been implemented all in just javascript and there's no c plus splits behind it in fact you can go ahead and create your own event emitter objects completely from scratch of course given the fact that you know some advanced jobs or concepts but if you know it's pretty easy to do that you'll see what i mean when we take a look at its source code in just a minute now this is just a pattern this is just javascript and the reason it's there is because if you recall in the previous video we said that node.js is event driven meaning that you issue commands instructions to the computer and you wait to respond back to those commands in an asynchronous manner again by asynchronous we mean that your application will continue its work while waiting for those events and this event-driven nature isn't something exclusive for note it's actually used in a lot of other software technologies in a lot of other programming languages one of the examples would be the operating system itself the os uses a lot of events a lot of asynchronous stuff is actually happening in it let's take a look at one example in the operating system so suppose that you have your hardware again you have your cpu your ram your storage and your network card which are all on a motherboard and there is an operating system running on top of it now your cpu let's say that it has two cores or it has it could only handle two threads now each one of these orange rectangles could only do one thing at a time now we could call them threads a core let's not really worry about terminology they're actually different things but for now let's just call them one of those things it doesn't really matter the important point here is that each one of them could only do one thing at a time so if you run a for loop on one of these cores that core is going to get completely occupied until it finishes that for loop okay let's also say that you have a keyboard attached to your system now let's also assume that you have created all of this hardware and this operating system yourself completely from scratch and now you want to handle what's going to happen if the user presses these keys on the keyboard now generally you could do it in two different ways you could either do it synchronously or you could do it asynchronously now if you want to do it synchronously you have to allocate one of these cores just to be able to read from this keyboard so one of these cores is going to constantly check your keyboard to see whether or not the user has pressed a key and then respond to that so you're actually killing one of these precious cores just to be able to handle a simple thing such as reading from the keyboard now this way that i talked about which is the first way is you're doing it in a synchronous manner so you're constantly checking your keyboard for that thing to happen now another thing you could do is to do this operation asynchronously meaning that you're not going to constantly just allocate one of your cores to constantly check this keyboard what you're going to do instead is that you're going to issue a command issue something to your cpu whenever a user presses something on the keyboard so in that case imagine i press the key letter a you're going to issue this thing now in the operating system we call these things an intra so your cpu sits right there but you could issue entrops to it and your cpu is going to respond back to those interrupts now again let's not really worry about the terminology we could call it an event commands anything it doesn't matter the point is that you're sending something to your cpu and your cpu is going to handle it and in this way you're not actually killing one of your cores whenever users presses something you're constantly going to send something to your cpu and then your cpu is going to handle it in just a second which is a lot more efficient to do now this is called event driven we're issuing commands we're issuing events and our cpu is responding to those events and it does them asynchronously all right now in the case of node it's just like that you define events you issue commands and then you wait and respond back to those using callbacks now here's where the event of our objects will come into play all it does is to give us a way to deal with this asynchronous event-driven nature of node.js in a little bit better way again it's just a pattern and it makes your code more readable and more manageable that's all for example here imagine that you have this piece of code app.on request and what it does is that whenever a request comes into your application this callback function will run so imagine someone on the outside internet specifies your domain name and they send that request that request is going to come into your computer imagine this is the internet so the request is going to come into your computer first it's going to get to your network card your network card is going to pass along to the operating system the operating system is going to investigate that request and see how to handle it now in this case that might have a port number like 8 000 and that 8 000 port number is associated with this node.js instance this node.js process so your operating system is going to pass this request to that process to this node.js process now node.js this love uv project this little bb package will kick in it will get this request and it will somewhat somehow using this events loop thing execute a callback function and that callback function will execute this callback function inside of this on method so if that last part is a little bit more confusing to you i'm going to elucidate it in just a minute by taking a look at another diagram so yeah this is the idea of event emitter now whenever someone comes into your code and sees this part for example app.on or an object.on they will immediately understand that that part is there to respond to an event so that's pretty much it that's all that this event emitter object does so here i'm back in my coder and again i have my on methods and i'm also submitting that event so again remember i'm going to say this one more time this is just a pattern and whenever you're doing this when we're using this on methods and this emit method you're not actually doing anything asynchronously you're not actually issuing any command you're not actually reaching to the library object or anything like that to understand what exactly happens when you call this odd method or the submits method let's take a look at another diagram to understand this a little bit better so that you know that this is all just javascript [Music] so whenever you're using the event or object you basically have this master object and when you run the on method like this for example on foo and then a function what you're doing is that you're pushing a function on to this master object and that's actually all that's happening inside of event emitter when you run this on method you're just pushing functions inside of this object and you could do it multiple times or you could do it with a function that accepts a parameter or a couple of different parameters it's completely fine and whenever you're doing this whenever you're calling this on method you're pushing new functions to that object pretty simple right and you can also do it with different event names in this case we have pushed three different functions with the name foo you can also do it with another name for example bar if you do that again you're pushing another function to that object so this is what happens when you call the on method now when you emit something when you emit an event in this case let's assume that we're going to admit an event with the name foo in this case the event is going to go to this master object it's going to loop through everything that it has and it's going to run all those functions associated with this event name so it's going to run this first function the third function and also the last function and it's not really going to do anything with this last function because the events name associated with that function is bar and here we're emitting the foo event and you could do this again multiple times so you could do it again and you could do it again this time you could also do it with a parameter now in each one of these cases you're also again doing the same thing you're going to this object and you're calling all these functions with that name now what actually happens is that these functions with the same name are inside of an array so all these foo functions are inside of an array so this is an object and this object has two items inside of it the first item is foo and the second one is bar the fu and both of these two are arrays so they hold arrays the first one which is foo has an array of length three and it has three functions we're going to take a look at that in just a minute so this is really what happens when you run the on methods and also the emit methods in this case we ran the mid method three times so we're going to run these functions three times each one of them three times we could also emit the bar events like this and in this case we're not going to touch these functions these foo functions and we're only going to run the last function the bar function okay now let's see this in action so i'm gonna go back to my code editor and run these functions so in our example we had three on methods so i'm going to copy paste this two more times this one i'm gonna change it to an event occurred one an event occurred to and for the last one i'm also going to specify a parameter x and i'm going to say an events say an event with a parameter occurred and i'm also going to log the parameter name like this x and i'm going to emit the foo event okay let's run this file and see what's going to happen so i'm going to head over to my terminal and i'm going to run node.app.js so as you can see the first function ran an event occurred one following that the second function and event occurred to and then the final function with a parameter and events with the parameter occurred we're also logging the parameter which is in this case which is undefined now what i could do is to specify a parameter right here so i could say some text like this on a run again and again those exact functions are gonna run but in this case this last one is also going to have a parameter to log so i'm not i'm not getting undefined i'm getting some text and we could do this multiple times let me emit this one more time so i'm going to say my e data metfoo and in this case i'm not going to specify any parameter whatsoever so think about it for a minute so what's going to happen in this case how many logs do you think we're going to get so the cement method is going to go ahead and run all of these functions once done the second emit method is going to run and this is going to run again all of these functions one by one but in this case it's going to specify a parameter to each one of them so let's go ahead and run it and as you can see the first submit method ran and we have undefined because we're not passing any arguments to each one of these functions and then the second with method ran but this time with a parameter now again remember that these will happen in order so if you change this one with that one like this in this case i'm going to get first and event occurred two and then anaban occurred one because i'm running this prior to this one let's run it one more time and then occur two always happens before an event occurred one okay [Music] now in our example we also have this bar method so i'm going to define it my e dot on bar a function like this and instead of this function i'm just going to log and event occurred and i'm going to say just bar like this and now what i'm going to do is to emit that bar method like this so mye.mit bar let's run it and sure enough in this case we also get that last lock and events occurred bar okay so pretty simple as you can see we're not doing anything crazy we're not talking to look pv we're not doing anything asynchronously we're just adding functions to an object and then we're looping through that object and running functions that we want using these met methods now the on animate methods are two of the most important methods to understand about this event emitter objects but there are also a couple more methods that could be good to know like the once method if we go back to our diagram if we run objected once instead of object.on so it acts kinda like the odd method we're still pushing something to this object but in this case no matter how many times you emit that event it's only going to run that function once so if you say object to the met bar if you do it a million times this function here is only going to run for one time so it's only going to run once so what really happens is that after this listener function runs after you emit once this listener is going to get removed from this master object like this so the rest of the emit functions are not going to have any effect whatsoever you could only emit it once and once it runs that listener is going to get removed so after the first emits the rest will be like that you're emitting an event that doesn't exist that you haven't defined a listener for if i go back to my code editor and emit this bar method a couple times like this and i'm going to comment out these two lines if i run this i'll get that log for one two three four five times so i'm emitting this event five times and i'm running this function five times now if i change this on to once like this and i run again in this case i'm only going to run that function for one time so yeah that's pretty much it's about ventimeters and we explored the mitts method and the on methods which are the two of the most important ones in the ventilator object and we also talked about the watts method there are actually more methods available on this object but we're not going to talk about all of them in this video you could just refer to the node.js documentation and all of them are explained pretty clearly in fact let's go ahead and take a look at it together so i'm going to open up my browser and i'm going to the nodejs.org website [Music] and i'm going to go to the docs version 16 api and right here i'm going to click on the events section now if you try to read this through which i highly recommend now that you understand the concept you'll see that pretty much all of them are pretty easy to understand here we could see a very simple example that we just saw defining a new listener and emitting that event and of course if you want to use the this keyboard you have to change your callback syntax to use the function keywords rather than using an arrow function again you could read about all of them here in this article there are also some things to watch out for if you want to use some asynchronous codes and handling errors is also pretty easy with event emitters all you have to do is to listen on the emit on the error event it's a reserved event name in lgs so this error one where you want to listen on it whenever something goes wrong and one of your listeners or when you're admitting something that listener is going to kick in again read more about it right here i guess we talked about pretty much all of them and the rest that we didn't talk about are pretty easy to understand for example this new listener it's just whenever you listen for it and you add new events on that thing this function is gonna run [Music] remove listener add listener mitts event names it's kind of intuitive to understand what they do just by looking at the names of these functions but if you want to understand more about them please make sure to run the codes play around with it and i'm sure you're going to understand what's going on okay i guess that's pretty much it there's also something else that i wanted to talk about here in this article if you scroll down you will see something that is not really related to event emitters but it's kind of related to events actually it's really related to events and that's event targets and node event targets if you read and see what the documentation has to say about them they're actually just an implementation of the event target web api so it's just there to make node.js more standards more standard with other javascript versions if you have used javascript on the front end working with dom and all that kind of good stuff you have used things like add event listeners so this is just there to make it more standard in fact if you scroll down you're going to see a lot of things that says this is not used in og.js and is provided purely for completeness so again that's something that i wanted to mention but don't really worry too much about this event node event targets and event targets nodejs just has implemented that recently in fact i guess it was in version 12 or 14 i'm not quite sure but it just came in recently but if you understand the concept behind advanced emitters these are actually pretty simple to understand it's just the same it's just javascript nothing too crazy really so now i suggest that you come here and focus on this events section all the way to here only to here up until event target and event api if you want you could also read this event target but i don't really recommend to make yourself confused about this just focus on the evaluator objects for now okay now as i said before it's just javascript this event object there's no magic behind it you could actually go ahead and implement it yourself if you want and what i'm going to do right now is to do just that now we're not going to implement all of this ourselves however i will show you an implementation that has been done by someone else so i will give you a link it's to an article to freecodecamp.org [Music] and the title is how to code your own event emitter in node.js now it shows and demonstrates how we could implement every single last one of those functions actually not every single last one of them but the most important ones like the emits ones off on and listener accounts and here we can see how they are implemented now what i want to do actually is to scroll all the way down and grab the complete code so here's the complete code i'm going to copy paste this if i could scroll up here so we have this event emitter class i'm going to go to my code editor actually my terminal and i'm going to create a new file called dot events.js exact same name as this one doesn't actually the name doesn't matter but anyway so i'm going to open that events my coder events and i'm just going to paste that code in and right here at the top i'm going to export this class so i'm going to say module.export equals this class [Music] and now what i could do is to go back to myapp.js file and right here instead of including this events file which is in the node.js source code i'm just going to add this before it so that now i am including it off of my custom file i'm going to save it and run my code again so i'm going to say net add node app.js and we get the exact same result as before so everything is going to work as expected actually i'm going to come uncomment these two lines and run it again and all is just here as before so let's go and take a look at the implementation here we can see that we're defining that master class so here's our actually master object excuse me so here we have our master objects and here we have our methods now the on method that we talked about is when you run this it's going to run this method at listener and it's just going to pass along that event name and that function now here what we're doing is that we're defining a new array and we're pushing onto that ray so here's where we're defining an array if it doesn't exist we're defining it or we'll just keep having that same previous version of that array and then we're pushing that new function on top of it [Music] and whenever we emit an event right here all that's happening is that this function will grab the array from the object that has the key name of this event name and then it's looping through that array right here and calling all the functions one by one and also passing the arguments so imagine we have this master object here i keep calling it master object when i'm saying master object i'm just referring to this object here it's just a normal javascript object okay so imagine we have this object so we have this event called foo which is just a property of this object and inside of it we'll have a couple of functions maybe two now these functions are different but just go with it right now this con function has its own content and this function has its own unique contents and then we might have another event called bar this one might only have one function now when you're emitting something for example emitting foo this function is grabbing this item from this master object so it's grabbing this array so this array is going to be f and s and then we're looping through this array and calling every single one of these functions so that's basically what happens when you emit an event just grabbing something from the objects and looking through that thing which is an array okay and then we also have some other simple methods like the listener count and what it does is that it will return the length of one of those arrays so it will grab that again and then it will return the length pretty simple we also have the once methods which we talked about and this function will just like the on method add that function to one of those properties and then it will immediately remove that function from that array as soon as we call it so we call the function and then we remove it actually i realized that this function is kind of buggy not actually this function but the remove listener function if you try to run it it will not work and just to show you how it works right here i am including this events actually i had to pause it here for a minute or two to figure out what's going on here so i'm defining this once method and i'm emitting it five times now you would expect to only get this log for one time but in this code we're actually getting it multiple times and it's because this remove listener function doesn't work as expected here it's checking to see if two functions are equal to each other but you can't do this in javascript now if we want to fix this let me try to do it pretty quick i hope i'm not wasting time trying to fix this code but anyway just so that you have something that works so we have to call the two string methods on these functions and also here in our for loop what we have to do is to change it to zero and then i less than equals to less length than i plus plus [Music] okay now if i try to run it again i'm only getting it for one time so that was also a quick fix in this code but anyway i think this is pretty much it this is also the custom implementation of advanced emitter if you want grab this code i'll put the link down below and try to play around with it to get a better solid understanding of how the event emitter object works in javascript now if this piece of code doesn't make a ton of amount of sense to you it actually has nothing to do with node.js and it's just related to javascript so you have to understand some concepts like this what's gonna what's going to happen if you try to do this use this syntax on an object and some other javascript concepts like prototypal inheritance the class syntax you need to understand that functions in javascript are first class meaning that for example you could pass them around as arguments of other functions just like other primitive types that you pass to functions for example here and this on methods it accepts a function as one of its arguments and then it is passing that to another object to another function excuse me so you also need to understand functions as first class and i'm not going to teach you these jobs or concepts since this is a note course and not a javascript course i will however give you a link where you could learn about all these topics yourself if you want so refer to that article that i talked about in the setup video link is down below and find a section that says something like event emitters and spend some time reading the articles and other resources that i have included with that section and once you do that come back to this code and i promise you that this will make a lot more sense to you all right now before i end this video let's also take a look at the source code of node.js related to the ventimeter object so i'm going to go to the node.js website right here and in the event section i'm going to scroll down and find the source code right here right below the title it says source code and then a link i'm going to click on it it will redirect me to the github the source code of that file events.js which is in the lab folder that we talked about in the node.js under the hood video let's zoom in a little bit and let's try to take a look at the source code now you will realize that this is a lot longer than that custom file that i gave you almost 1 000 lines of code but a lot of it is actually error handlings and some extra functions that were not included in that custom file now let's try to see what is what this file is exporting so i'm just going to search for export and you could see that four things are getting exported from this file the events of their objects and the ones and odd methods as standalone things that you could include and also the get events listeners now please come to this file and try to read it see some of the patterns that are used and i guess let's also take a look at the emit implementation so i'm going to search for emits here we go it's on the prototype of that ventilator objects we used the class syntax but here it's using the prototypal prototype syntax which is just a syntactic sugar so classes are just syntactic sugar for this prototype so here the emit function is defined we're checking for some errors and if we scroll down again more checking for errors here we're grabbing that ray so we saw the syntax we're grabbing that array from that object and we're saving it to this handler some more error checking right here and then i guess we should have somewhere for loop right here so we're looping through that handler as you can see and we're calling them and we're also passing the arguments so this might be a little bit more complicated than that simple custom version we saw previously but this is just the same concept example here we're calling the apply method which i don't know if you know this or not it's again related to javascript and i'm not going to talk about them here but yeah this is also the source code of node.js it's actually pretty simple to understand of course given the fact that you understand those advanced javascript concepts you could just come to this file and read all these functions and understand pretty well what's going on here all right [Music] so that's it about this video and event emitters will make use of this object later in the course as you'll see that it's heavily used in different parts of node.js a lot of apis in node are actually inheriting from these objects and therefore we could use methods like the on and emit on them as we'll see later in the course not just the node.js itself but also some of the well-known nodes packages out there are also use event emitters all right that's about this one and i will see you in the next one
Info
Channel: Cododev
Views: 9,911
Rating: undefined out of 5
Keywords:
Id: 7BhD2txiITM
Channel Id: undefined
Length: 35min 13sec (2113 seconds)
Published: Sat May 21 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.