Rx.js Fundamentals Merging Timelines
Transcript from the "Merging Timelines" Lesson
>> So we gonna talk a little about, we've dealt with like individual strings, we've even had some observables that will listen to others. But now we're talking about some strategies for kind of combining and merging multiple observables together. Really great example if you think about that counter we had before.
[00:00:18] Yeah, we have the interval eventually listen to the start and stop button but those are kind of just two sides of the same coin, right? It'd be great if we could simply like create a stream on whether or not they've hit we should be going or not. We have a version of that here.
[00:00:33] This is kind of a quick tool that I built. We'll see how to build like a simplified version a little bit. But a quick tool that I built to kind of visualize a bunch of different ideas observables together, right, and as we kind of merged. But we're gonna build a little bit together before we use it cause right now these buttons don't do anything.
[00:00:54] So I'm gonna kind of get at least a start and the pause working. And this will be a little bit similar to what we eventually kind of, we've seen before and we'll take it forward as we go along here. Okay, so I've got the start and let's actually grab the pause button And they are each individual ones, now what if I wanted to merge them together.
[00:01:20] And then yeah, maybe start we want to be yeah, I guess you should be running. Pause, no, you should not be running. That seems reasonable, right? So we could theoretically take each one and we could save .pipe. Map to, map this one to true and we'll say .pipe Map to and we'll map that one to false.
[00:01:50] And now we just want one stream of either the true values or the false values. So let's make a new observable. And that's going to simply use a new kind of creator we just have from event, this one's called merge. You take a lucky guess what it does, it will merge two streams into one.
[00:02:17] So we'll start with the start and the pause and we'll merge them together. And we'll even start with saying by default, even before they click a button, let's just start with false. So we'll give it effectively like a default value even before anything gets admitted from either one of those events.
[00:02:41] Great, and we'll start with the simplest possible thing here we'll say is running and we'll subscribe to it, console log. All right, the really cool thing here is you'll notice that we didn't have to subscribe to start and pause individually. But we were able to kind of merge them together and when we subscribe to the merged stream, we will effectively be subscribing to the two child streams in this case.
[00:03:12] So let's just verify that that does what we think it does. Starts out with false, it starts, it says true, false, true, great, everything kind of works. At this point, instead of logging into the console, I have this setStatus which is gonna manipulate the DOM a little bit So now you can see it starts, it's paused, it's running, it's paused, it's running, right?
[00:03:41] Cuz it's based on what is happening in that case. So setStatus is basically, we can look at it in the utilities but it's like if true show running in this div, if false show paused. So we kind of get that functionality out of the box for free. Now, that's merge, and there's a bunch of different ways that we might want to deal with merging two times, to timelines, right?
[00:04:08] So what we're gonna kind of do is play around with visualizing this. You'll see, you can't really see them yet, but there are three columns. And so we're gonna take two different streams, we'll look at some of the different strategies for merging them. The first we will call our first observable, the middle stream will be our second observable, and the third one will be our combined observable in this case.
[00:04:29] So what happens when we merge them in two different formats. We saw merge, but you can imagine all it does is it takes any of the children, admit an event, merge, shoots that event on through. It's just combining two in the simplest most direct fashion. Have this little helper function called Bootstrap and all that does is utilities I've got a little bit more complicated, observable, we'll see similar versions of it later.
[00:04:56] That kind of just powers this whole exercise, so we can visualize it. So the only thing that I have to do at some point is pass the three observables to this Bootstrap function. It is not ordinary extra thing, it is simply to get this thing up and running.
[00:05:11] So one of the things I wanna do is just create three different streams. I do have this helper called label with, label with is simply it's annotating it with the right class name and the label. It's just basically doing So I can visualize things it's not part of our Ext JS.
[00:05:27] I'm just mapping the value to have as of actually a version of map to but I also do the other things I need to make them look their correct colors. So if we flip over and you clear this out you can see I can start it runs one, two, three and then it finishes.
[00:05:46] So these are three independent streams but combined is capable of bigger and better things combined should be the merge of these two, right? So if we go ahead and we can kind of replace this here we can say, okay, merge first and the second observable. So now combined is any event that comes through first, any event comes through second is now combined, merged into one observable stream.
[00:06:19] So, let's take a look, yeah, we have three streams going still. We've got first which is the first one independent. Second which is the second one independent and then combined which is both the first and the second one kind of merged into one stream. With merge it should look basically like the timer's are slightly are similar so they could come in a little bit interweaved.
[00:06:42] But basically anytime either one of them admits we should see it on the combined stream as well, so let's go take a look at that. So we've got that, we actually only need to call this one merge I don't need to label it Awesome so you can see the color coded correctly, they're all kinda coming into one combined stream in this case.
[00:07:12] And that might be what you want, right? A lot of times, that is what you want, like take these two things, for our start or stop button. We don't, like whenever one of them happens, pass it through to this combined stream. And a lot of times that will solve for the issue that you want.
[00:07:26] But there are other strategies, and we'll actually see some of these, play out later. Where you might want to have a little bit more of an opinion on the order, right? So, you might wanna say, hey, I have these two streams, three streams, 10 streams, what have you, right?
[00:07:46] I have these streams, what I wanna do is play through all of the first one, then play through the subsequent ones, right? And merge is not gonna do that for you, merge is first come first serve, right, whichever one admits it's into the merge stream. Concat is going to go ahead and say, cool I want to run through the first one to completion.
[00:08:09] It's one stream we'll do everything in the first stream, we'll do everything in the second stream, so on and so forth, right? And you can do some interesting coordination with this, which is, okay, I want to do everything I need to show the loading page, right? Then I wanna do everything I need, whatever is involved there, I don't care.
[00:08:30] I wanna play through the first scene. We'll do everything for the second scene, everything for the third scene. So we can go ahead and we can just swap this one out for concat. And we'll see that this behaves slightly differently. Now what I want you to notice is it doesn't matter when things get admitted from the second one.
[00:08:50] The combined stream won't even subscribe to it until it is done with the first one. So you see they are going, we don't get anything from the second stream until we finished everything on the first stream. And then we begin listening to the second one, right? So merge these two streams, but work on them in order.
[00:09:10] Take the first thing, finish it to completion. Move to the second thing, finish it to completion, so on and so forth. We've got another one called race, anyone have a lucky guess what race does?
>> Yep, right, well myths first in this case, so it's kind of promise dot race.
[00:09:28] Promise dot race is like listen, here's a bunch of promises. Whichever one of you resolves let's go for it. Race is also similar where it'd be cool. Here's a whole bunch of observables. Start with whichever one admits first, I don't care. So we'll swap that one out. And let's say that first we're gonna have it take 1500 milliseconds.
[00:09:59] So, if you can kind of see that the second one started first and the first one could go on forever. It doesn't care like the combined one only talks to winners, right? I know it doesn't talk to anyone comes in second place. And so as a way to say, okay, I have these two things going on whichever one admits first.
[00:10:21] One of the things we will see later is you wanna show a loading indicator but maybe only after a certain amount of time, right? So hey, two seconds for loading indicator. If the data comes back before two seconds, the data wins. If the data has not come back after two seconds, well then the loading indicator wins, right?
[00:10:44] Show the loading indicator, right? You still need to do something with the data and we'll figure out how to manage that all in a little bit. And it could be cool, show the loading indicator, then get the data, then take everything down, right? So this ability to merge things, but also sequence them and figure out the order of operations between them becomes incredibly powerful.
[00:11:06] Another one, you'll see sometimes it's just called fork join. It's not the most glamorous name in the world. And to kind of say that's also deprecate in this case, but it is real common. So it passed the bar in this case, so what this one does is it waits for them all to finish and gives you an array of the last value of each.
[00:11:31] So nothing in the combine stream. They finish, I get the two last values from each of them, right? Cool, so we have different ways to mix and match these. Now where this becomes interesting is when we kind of put them inside of other observables. We can kind of get a little bit more powerful with that as well.