Advanced Asynchronous JavaScript

Q&A: Multi-dimensional Observables

Jafar Husain

Jafar Husain

Netflix
Advanced Asynchronous JavaScript

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

The "Q&A: Multi-dimensional Observables" Lesson is part of the full, Advanced Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

After reviewing the problem statement, Jafar takes questions from students about larger than two-dimensional observables and the difference between concatCall and switchLatest.

Preview
Close

Transcript from the "Q&A: Multi-dimensional Observables" Lesson

[00:00:00]
>> Jafar Husain: We've taken some time to review these, so I'll remind you what the problem is. We have this tasks, which is a two dimensional observable. Every single time we get an inner observable, the platform's saying, hey, I'm about to do some expensive work. It's gonna take me awhile.

[00:00:16]
And as long as the platform is doing more than one task, I don't want to allow animations. So as soon as one task comes along, I switch to false. And then as soon as the platform has done all of its tasks, I switch to true. And then as soon as a new tasks comes along false, and so on and so forth.

[00:00:34]
So what we're gonna do is we're gonna gradually move from tasks to animations allowed, using the functions that we've learned. Sorry guys at home, I haven't been as good about staying on top of the questions. Is it common to have larger than two dimensional observables? Well, larger than two dimensional, no, it's quite rare.

[00:00:51]
In general, well, let me put that differently. In general when you use some function which creates a two dimensional observer, typically a map. Well let's take a step back. The most common pattern we see in UIs is you get an event, you kick off a network request, and then you do something with the result, right?

[00:01:10]
So for every event, you may wanna kick off a network request. That simple, regular pattern creates two-dimensional observables, right? Cuz we take our clicks event, you remember the clicks event? And then we map over it, and then we return the result of making a network request, which is also something we turn into an observable.

[00:01:30]
And so if we create a network request, if we create an observable for every piece of data in another observable, we create a two-dimensional observable. So let's take an example of this.
>> Jafar Husain: So here I have an array. If I do this, what do I get guys?
>> Speaker 2: A new array.

[00:01:52]
>> Jafar Husain: Exactly what do I get?
>> Speaker 2: Two dimensional array.
>> Jafar Husain: Why do I get a two dimensional array? What does this have to do with network requests and events? Well.
>> Jafar Husain: So here I am, for every button click, I'm pulling the currently selected stock out of a select box and I'm getting the price for that stock.

[00:02:33]
If getpPrice works like this,
>> Jafar Husain: This is somewhat aspirational.
>> Jafar Husain: Right, so getPrice returns me an observable. It eventually gives me an extremely high stock price, right? getPrice is a function that creates an observable. So how many dimensions is this observable right here?
>> Speaker 2: Two-dimensional.
>> Jafar Husain: Why is it two-dimensional?

[00:03:05]
Who says one, out of curiosity? Does anybody say one?
>> Jafar Husain: No, we all think it's two-dimensional? Why is it two-dimensional?
>> Speaker 2: Because the initial observable is we're mapping over the values and we're creating a new observable for every value, so it'll be observables inside the observable.
>> Jafar Husain: Yeah.

[00:03:23]
>> Speaker 2: And we need to use merge map.
>> Jafar Husain: That's just like this example right here. Well, so that's interesting. I heard you say we need to use merge map. And for those of you who don't know, merge map is just a map followed by a merge all. So, in other words, in order to flatten it we could do

[00:03:43]
>> Jafar Husain: Is this what I'd want in a UI?
>> Jafar Husain: Is it? I don't know.
>> Speaker 2: Switch map?
>> Jafar Husain: [LAUGH] Yeah, that's a good guess. I'd probably want switch latest here. Who thinks another operator like, like concatall, so we got three, right? Merge all, concatall, switch latest. The reality is it probably depends on your UI requirements, but most of the time you want to ignore the last three requests they made for stock prices and you only want the current one, right?

[00:04:12]
The last thing you want to do is give a broker an old stock price, they tend to get really upset about that. So I would use switchLatest, because if somebody goes [SOUND], we all know brokers are impatient, right? If they do that, do I want five competing, racing network requests to the server?

[00:04:29]
I wanna throw away the last four, and just keep one. And so that's why I'm gonna use switchLatest, right? If I was to use mergeAll, a couple of bad things might happen. One is I'd kick off six concurrent network requests, maybe that's what you want. But is there any guarantee that those network request results are gonna come back in the same order in which they were kicked off?

[00:04:50]
No, right? I got a race condition. So switch latest helps me solve that problem. Now, concat all would also solve that race condition problem. It would wait for the first request to come back. Then it would make the second request, and so you'd always get the latest numbers, right?

[00:05:07]
But it would also take a super long time. Remember how concatAll elongates time? Cuz it never stops the current network request. It waits for the first one to be done, and so the second one. So you can imagine me doing this [SOUND] and cueing up a bunch of network requests, which is probably what I don't want, right?

[00:05:26]
So the answer to your question is two dimensional observables are very common, or well, sorry, the answer technically was is larger than two dimensional is common. Not really, there are some cases where you would want larger than a two dimensional observable, but that's not very common. So the difference between mergeAll and merge, this is a great question.

[00:05:47]
So we learned to merge we learned concat and we learned mergeAll and concatAll. MergeAll and concatAll operate on two dimensional observables and flatten them. So if you have a stream of streams arriving, merge on concat. I'll look great for that. But sometimes you don't have a stream of streams.

[00:06:05]
Sometimes you just got two observables, or five observables, or nine observables. And you have them all right now. You just want to concat them together or merge them together and that's when you would use observable.merge. Cuz here, if you already have the observables, you can just plug them all in at once, does that make sense?

[00:06:26]
>> Speaker 2: Is merge an actual method that you use as an instance method?
>> Jafar Husain: Yeah, you can use both if you want.
>> Jafar Husain: I prefer to use it statically cuz I find that's a little harder to read when I format it then. But you're absolutely right. You can call it like this or you can call it like this.

[00:06:50]
I find statically when you indent it. So it'll clear that these two are kind of not dependent on each other but they are just being plugged together.
>> Jafar Husain: So awesome question, great question guys. Now does everybody understand the difference between concat, concatAll? merge, mergeAll?

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