Advanced Asynchronous JavaScript

Events into the Observer

Advanced Asynchronous JavaScript

Check out a free preview of the full Advanced Asynchronous JavaScript course

The "Events into the Observer" Lesson is part of the full, Advanced Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Before doing any work in an observerable until subscribe is called, Jafar reviews how to get events out of a DOM events out into the observer. Jafar takes questions from students.


Transcript from the "Events into the Observer" Lesson

>> Jafar Husain: So lets go back to our from event. So we're going to wait from now on before we do any work inside an observable, we are going to wait until subscribe is called. So help me out here, what am I going to do when subscribe is called in order to get the events out of the dom event into the observer.

Remember we're pushing events that we get from the dom event into the observer.
>> Speaker 2: Attached to the event handler?
>> Jafar Husain: Yeah, so we've got a dom element. We're gonna do addEventListener. We're gonna pass in the eventName. And now help me out, well, how does that event listener work again?

>> Speaker 2: It's gonna call
>> Jafar Husain: Right, it accepts a function right, and I'm gonna call observer next, and I'm gonna get an event object, and I'm gonna pump it into the observer, right?
>> Speaker 2: For conciseness can you just pass
>> Jafar Husain: You could, it wouldn't be as concise as you hope though because of the way JavaScript Function binding works, right?

So if we do this, can anybody tell me why this isn't gonna work the way we expect or want it to?
>> Speaker 2: Because of this?
>> Jafar Husain: There's a gotcha, cuz of the this object. Functions, right? In JavaScript, don't necessarily run, they're this object does not necessarily the function the object is hanging off of.

Here we're actually literally is you're going to pass the function reference through, and it's going to call it. So we need to do something like this and we need to make sure to bind it. And frankly that's not so concise anyways. So I generally prefer, rather than using bind, the explicitness of this.

Does that make sense? So okay, am I done? What's missing here?
>> Speaker 2: Cancel?
>> Jafar Husain: Yeah, right. We've hooked the thing up. But if somebody wants to unsubscribe from this event they're out of luck, right? So how do I do it? I return a subscription. Now subscription much like an observable, is just a function in object clothing.

So it has, it's just a function, it's just an object with one function. And so what am I going to do when somebody unsubscribes?
>> Speaker 2: Remove the event listener.
>> Jafar Husain: Remove the event listener.
>> Jafar Husain: Ran into a problem here.
>> Speaker 2: Same function at that point?
>> Jafar Husain: What?
>> Speaker 2: Can you actually remove that event listener with being a different function?

>> Jafar Husain: Yeah, how's that gonna work? That's not gonna work so well for me, right?
>> Speaker 2: Tie that function to a function on the object.
>> Jafar Husain: Okay that's interesting. So you what are you suggesting here, take this?
>> Speaker 2: Observable can have the call back, and you can unsubscribe from that call back.

>> Jafar Husain: So like you're-
>> Speaker 2: Call back just fires the
>> Jafar Husain: So like if I go this.callbackequals? Is that the type of thing you're getting at?
>> Speaker 2: I think so.
>> Jafar Husain: You know what, I think that would totally work. But one thing I don't want to do though, so I think it would work for one subscription.

And then the subsequent subscriptions would all try and stomp on the same member on the observable. So in general, we don't wanna store members on the observable. That's a really good guess. And why don't we wanna store members on an observable? Well, because you know what, that observable's just a wrapper for a function.

And if we put data on it, and I call subscribe 50 times, all 50 of those functions are gonna be trying to write to the same piece of data. The good news is, we don't need to do that, because in JavaScript we have closures. So I can just create a variable up here.

>> Jafar Husain: So let's think about, if I call subscribe 50 times, how many of these variables am I gonna get?
>> Speaker 2: 50.
>> Jafar Husain: 50, right? But if I did this dot handler, right, I'd have one observable and 50 functions all trying to muck with it. So in this world, we can use closures for pretty much everything we wanna do.

And that makes sense, because I've been telling you guys that observable is just the wrapper. Just an object that wraps around a function. So from now on, let's think functionally. If we need state, we can use a closure and a variable and just put the state right in there.

Turns out it's actually more convenient anyways most of the time. So does this make sense? Is this going to work?
>> Jafar Husain: Is there anything broken?
>> Speaker 2: We need to complete? Call complete.
>> Jafar Husain: Good question. Now does this observable complete?
>> Speaker 2: On unsubscribe?
>> Jafar Husain: Good question. This is exactly the type of thing that I want to bring up here.

Is there a difference between you unsubscribing and an observable completing? Are those two things the same thing?
>> Speaker 2: No.
>> Jafar Husain: Right, if you get up and walk out of the room right now in the middle of my lecture, right, is my lecture done?
>> Speaker 2: No.
>> Jafar Husain: No, you're just not listening anymore, right, and that's totally your prerogative.

But the reality is the lecture goes on, you've just decided to stop listening. Now, if you were the last person in the room and got up, I might decide well, there's no point in me standing here and doing this lecture. And later on we'll figure out how to build an observable such that if nobody is listening anymore, it actually stops.

But the main thing I wanna talk about here is the difference between an observable completing and you not listening anymore. Right? When you unsubscribe, it doesn't mean that that observable completes. So if you unsubscribe you're not gonna get [NOISE] complete being called, right? You're just saying, hey, I don't care about this anymore.

Doesn't mean the lecture was finished. Does that make sense? Now, again, if you're the only person in the room, right, I think I see a question. Sorry.
>> Speaker 2: We had someone wanted you to explain closure real quick.
>> Jafar Husain: Closure, yeah. A closure is a function that closes over a variable defined outside of that function.

So, here we have, you know what? Sorry, this is a bad example. Well, it's a slightly, yeah, it's kind of a bad example. No, it's a good example because here the variable being closed over inside of this function is what?
>> Speaker 2: Observer.
>> Jafar Husain: Observer, the reason why this is a closure, is that we're using a variable inside of the function that wasn't defined inside of the function.

If I did this,
>> Jafar Husain: I don't have a closure anymore, it's just a function that defines a variable, that lives to the lifetime of that function, and then when the function ends, variable goes bye bye, all right? So a closure is an interesting way of allowing us to kind of keep state because we can define a function, close over it by using it in a function.

And then that variable is gonna live for as long as the function that closed over it. So normally when we create a variable inside of a function, that variable goes bye bye and the data inside of it goes bye bye as soon as that function ends, right? But if we close over it like I have done here and then I hand this function to somebody else, as long as there's a function that's closed over that variable and someone is holding onto that function, the data in that variable lives.

And so as you're gonna see, basically we're gonna build our observable implementation today with just a bunch of closures. And if you've imagined if you were to visualize an observable in memory, it'd just be a bunch of functions closing over data holding on to other functions, closing over data.

And in the end that's fundamentally not that simple than a big objectory, and object oriented programming. In the end if you'd look at memory, they look kinda similar. You just got a bunch of data stored somewhere. Except instead of being stored under this object, we store it indirectly through closures.

Does that make sense? Hopefully that answered the question. But it's interesting to note that almost anything you can do with object-oriented programming and state on prototypes using this dot, you could also do with closures. I could do a whole other class on that one. But, the reality is they're actually equivalent.

So let's jump back to our problem at hand here. I've defined a handler.
>> Speaker 2: We were talking about complete if it makes sense.
>> Jafar Husain: Yeah, just we actually had a corollary of this earlier when we were talking about Timeout. Time out, somebody brought up hey, what about on airing?

Or what about airing? Well, time out's don't air, right? They never air, they never fail, right? Do events, do DOM events ever complete?
>> Speaker 2: Do dom events or DOM? One thing I was thinking of is that we could subscribe to the dom node removed and then have a complete on that for the element?

>> Jafar Husain: So you're saying so complete when the DOM element is removed?
>> Speaker 2: Sure.
>> Jafar Husain: Yeah, that's legitimate. Sure, of course the dom element could be then added back into the scene, right?
>> Speaker 2: Sure.
>> Jafar Husain: So maybe it's not super safe to complete just because the dom elements been moved.

Somebody might just be moving it.
>> Speaker 2: Okay, yeah.
>> Jafar Husain: So I'm just gonna submit to you that well some event streams don't end, right? Just like all the natural numbers don't end, right? Doesn't mean that we're, that's a problem. It's interesting to note that because of laziness, we can deal with infinite streams of data.

In fact, it's actually gonna be very common that we deal with infinite streams of data and one of the most common sources of infinite streams of data, dom events. Think about users. They can always click the button again. They can always move the mouse again. So, there's always the possibility that we're gonna get another event.

So, I think we're actually done. We don't, we're never gonna get an error from a DOM event. Well, there's a little more nuance conversation around that. Some dom events we can interpret specific DOM events as errors. But I think for the purposes, simple example were done. And so we got from event here.

So we've got an example of a hard observable, so why is this a hard observable? Even though it looks the same, really structurally it's timeout. What makes this hot vs this?
>> Speaker 2: You can miss events if subscribe later?
>> Jafar Husain: Yeah, it's because frankly all we're doing is we're adapting an underlying data source that happens to be hot into an observable.

And therefore, the observable itself is gonna be hot. Right, all we have done just hooking up to what's truly a hot data source, the event stream. But when it's set time out because we delayed doing the work until subscribe was called. We made sure that every single time you subscribe, you're always gonna get a result, cuz we kick off a timer just for you, right?

We can't do that with a DOM event, what would that even mean? So this is an example of a hot and a cold observable right here. And we've seen that there's really not much to observables, right? You do the work to set up the subscriptions so that the observer gets data.

And then when they call unsubscribe, you do the work to make sure they don't get called anymore, and that's about it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now