Use switchMap to avoid leaks when flattening

André Staltz
InstructorAndré Staltz
Share this video with your friends

Social Share Links

Send Tweet
Published 8 years ago
Updated 6 years ago

While flatMap is popular and convenient for flattening higher-order Observables, it can introduce new kinds of bugs related to subscriptions. In this lesson we will see how switchMap is a sensible default that avoids common bugs.

[00:00] The merge map operator, also known as flatMap, either name works, is quite impotent and common for solving some asynchronous issues. That said, it can create some other problems if you don't use it in the correct cases.

[00:14] Let's demonstrate that problem with this example. I have a click observable, then, I have another observable which depends on the clicks, and whenever a click happens, we will spawn a new inner observable which ticks every half a second. Then those numbers are put here in the console.

[00:33] Let's see that working. Once I click here, it will spawn new inner observable, and if I click again, it will generate a new inner observable, and now, there are two of them happening concurrently. The more I click, the more it's going to spawn these new inner observables, and this just keeps on going forever.

[00:51] Since these are infinite observables, these are never going to stop, so the more I click, it means that the more CPU and RAM we are consuming, and this doesn't stop. It doesn't have this cancelation logic into it.

[01:05] Flatmap doesn't provide us that. But there are other operators, one of them is called switchMap, which provides you cancelation built in. It works in a similar fashion than flatMap, except it has slightly different semantics.

[01:20] Here if we click, it will spawn a new inner observable, but once we click a second time, it cancelled, or basically unsubscribed from the previous one, and is now only subscribing to the most recent one. If I click again, you can see it cancelled the second one, and only took the third one.

[01:39] That means that at any given time we only have inner observable ticking. We don't consume more and more RAM and CPU as we go. That means that switchMap is usually a better default choice, because it has this cancellation built in. Now that works even for the example with requests, here, we had our system with mergeMap to get the requests from the server.

[02:08] Once we click here, it will give us that data, but we could have used switchMap here and it would have worked in basically the same way.

[02:17] As you can see, once I click here, it will give me that data. The difference here is that if I click two times very quickly, basically a double click, then it wouldn't perform two requests. It would cancel the request for the first click, like this. As you can see, I just got one data back.

[02:38] The conclusion is that when people use mergeMap, basically what they want to do is just flatten an observable of observables, but you need to realize that mergeMap is not the only flattening strategy, and if you don't know which strategy to choose you're probably better off with switchMap. By default, use switchMap, if you really know what you're doing, then go ahead and use mergeMap.