That’s pretty good, this seems like the observer design pattern
@compeng20137 жыл бұрын
Just got this as a 'take-home' interview question. Very similar!
@hackingthejsinterview2424 жыл бұрын
Something I wipped up in 5 minutes. This isn't exactly event emitter, but somwhat of the same thing, except a simpler way of understanding it without classes. This is definitely a great interview questions. Interviewer would have definitely ask something like, implement the pub/sub pattern you see all the time in JS. const Event = { events: {}, on: function(eventName, func) { this.events[eventName] = func }, fire: function(eventName) { this.events[eventName]() } } Event.on('event1', function event1() { console.log('event1') // event1 }) Event.on('event1', function event1() { console.log('event1 - override') // event1 }) Event.on('event2', function event2() { console.log('event2') // event2 }) Event.fire('event1') // event1 - override Event.fire('event2') // event2
@nvcbl2 жыл бұрын
I did something similar but with an array of functions and for loops
@guywald18 жыл бұрын
Excellent video. Implementing this in JS was something I was wondering for some time. Thank you.
@Samsul20133 жыл бұрын
Thank you Stephen. You just my timer saver... cheers!
@kariboo847 жыл бұрын
the " ...rest " just saved my virtual javascript life, great vid, peace
@ambitious_grass4 жыл бұрын
I was asked this interview question today and definitely struggled at first. Was able to complete it though!
@kalleneumann2035 жыл бұрын
Hi thank for the vid! One thing, the trigger seems not to forward multiple arguments with apply() this way, so I figured someone might try trigger = (eventName, ...rest) => { if(this.events[eventName]) { this.events[eventName].forEach( callback => { callback.call(null, ...rest); }) } } instead, which relays all arguments passed. Cheers!
@C0D3A22A22IN2 жыл бұрын
Thank you! Was stuck trying to figure out how to pass a parameter back to the callback for so long.
@nacimhoc8 жыл бұрын
You can avoid the if else statement in the "on" method by dirrectly push the callback on the event array after adding this line of code : (events[eventName] || (events[eventName] = [])).push(...).
Two questions here: 1. The trigger function will call *all* callbacks registered to that event with the specified arguments. So it follows that if: this.events[eventName] = [cb1,cb2,cb3] and I 'trigger' with trigger ( 'eventName', [arg1,arg2,arg3] ) that this will call cb1,cb2,cb3 thus: cb1(arg1,arg2,arg3) cb2(arg1,arg2,arg3) cb3(arg1,arg2,arg3) Let's hope all the callbacks take the same arguments.... 2. What's the point of the emitter? Can I get some use cases?
@usasikh18 жыл бұрын
Please do a video on Redux sagas :)
@MitchKarajohn7 жыл бұрын
Why did you chose to execute the callbacks with cb.apply(null, rest) instead of just cb(rest) ? Isn't it preferable that the callback keeps its context, in case it had something like "this.someProp" in its code?
@viktorsoroka45107 жыл бұрын
I have also noticed this. Actually "cb.apply(rest)" is incorrect. There is no possibility to skip the context argument for the "apply" method, so in this case "rest" is set as the context which is wrong. He did not pass any arguments to the callback so he did not spotted it.
@dokkenrox7 жыл бұрын
Using cb(rest) wouldn't work because rest is an array, and cb() would expect a set of arguments, not an array. He uses apply because it can pass this array to cb() as if it were arguments. However, using the spread operator for the callback, like cb(...rest) , could also work instead.
@arunkant6 жыл бұрын
bound function do not lose this when used via .apply(), so no context is lost
@HarpreetSingh-jd3tu Жыл бұрын
Why do we need an event emitter class?
@КонстантинГиль-р9я8 жыл бұрын
Hi, if u call method "trigger" like this trigger('change', 'vasya'); And early define like this ee.on('change', (name) => { console.log('hello ' + name + ' there!'); }); Result will be "hello undefined there!" Maybe need fix this code: this.events[eventName].forEach(cb => { cb.apply(rest); }); to change this.events[eventName].forEach(cb => { cb.apply(this, rest); }); Or i dont understand purpose of rest arg?
@21523115641325428 жыл бұрын
cb(...rest);
@urbansilhouettemedia5 жыл бұрын
/* The Prototypal approach, in case you needed to pass objects rather than a pointer. ----------------------------------------------------------------------------------------------------------> */ const EventEmitter = function(n){ this.name = n this.events = {} return this } EventEmitter.prototype.on = function(eventName, callback){ this.events[eventName] ? this.events[eventName].push(callback) : this.events[eventName] = callback } EventEmitter.prototype.trigger = function(eventName, ...args){ !(this.events[eventName]) || callback(this.name, this.events, args) function callback(n, eventList, a){ for (n in eventList) { (eventList[n]).apply(this, a) } } } /* As seen below ----------------------------------------------------------------------------------------------------------> */ let foo = new EventEmitter('foo') foo.on('foo', (a) => { console.log(a.handle) a.crow() }) foo.trigger('foo', { handle: 'bar', crow: () => { setInterval(() => { console.error(' { [ [!!!SQUAK!!!!} } }') }, 500) } }) console.log(typeof foo) console.log(typeof foo.trigger) console.log(typeof foo.on) console.log(foo.__proto__)