SwitchMap

.switchMap() is a very close cousin of .flatMap(). The difference between them is that .flatMap() will return wait to return all of the elements from the Observables that were created inside .flatMap(), while .switchMap() will only return elements from the newest Observables that were created from the newest values.

The easiest way to explain this is by example. First, let's take a look at how .flatMap() will work with this:

Observable.interval(3, TimeUnit.SECONDS)
.take(2)
.flatMap(x -> Observable.interval(1, TimeUnit.SECONDS)
.map(i -> x + "A" + i)
.take(5)
)
.subscribe(item -> log("flatMap", item));

This will basically produce the two sets of items that will be numbered from zero to four. In total, there will be 10 items printed because the first .interval() produces two items (limited by .take(2)) and each of these items will produce another five items (limited by .take(5)) with another .interval() inside the .flatMap():

flatMap:RxComputationThreadPool-2:0A0
flatMap:RxComputationThreadPool-2:0A1
flatMap:RxComputationThreadPool-2:0A2
flatMap:RxComputationThreadPool-3:1A0
flatMap:RxComputationThreadPool-2:0A3
flatMap:RxComputationThreadPool-3:1A1
flatMap:RxComputationThreadPool-2:0A4
flatMap:RxComputationThreadPool-3:1A2
flatMap:RxComputationThreadPool-3:1A3
flatMap:RxComputationThreadPool-3:1A4

Now, let's try the version with .switchMap():

Observable.interval(3, TimeUnit.SECONDS)
.take(2)
.switchMap(x -> Observable.interval(1, TimeUnit.SECONDS)
.map(i -> x + "A" + i)
.take(5)
)
.subscribe(item -> log("switchMap", item));

The output of this Subscription will be a bit different:

switchMap:RxComputationThreadPool-2:0A0
switchMap:RxComputationThreadPool-2:0A1
switchMap:RxComputationThreadPool-3:1A0
switchMap:RxComputationThreadPool-3:1A1
switchMap:RxComputationThreadPool-3:1A2
switchMap:RxComputationThreadPool-3:1A3
switchMap:RxComputationThreadPool-3:1A4

We can see that the emissions from the first .interval() that was produced inside the .switchMap() stopped immediately when the second .interval() was produced. That's what the .switchMap() does--as soon as the next Observable is returned, it terminates the one that was used before it, and produces items only from the newest Observable.

This is useful, for example, in settings management--we might want to terminate the previous Observable that was created with the old values as soon as the new parameters arrive.

Alternatively, consider a case when we receive an item in an Observable, and we start a network request. If the second item is received, and the first request was started with .switchMap(), the first request will be canceled before the second network request will be made. If the request was started with .flatMap(), the Observable will wait for the first request to complete before starting the second one.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.152.58