mariachiacero.com

Understanding the Differences Between switchMap and concatMap

Written on

Chapter 1: Introduction to RxJava Operators

It has been quite a while since my last blog entry, and I'm excited to dive back into it with this topic. RxJava offers a robust library filled with numerous operators. While its power is undeniable, understanding how to utilize these operators effectively is crucial; otherwise, it may lead to unexpected behavior. One must thoroughly comprehend each operator, as time can often blur the finer details. There have been instances when I had to revisit the documentation to recall those critical nuances.

Both concatMap and switchMap serve as operators that transform one Observable into another.

Section 1.1: Understanding concatMap

The concatMap operator performs a concatenation of emissions while ensuring that they are ordered. A key point to note is that it waits for the inner Observable to complete before subscribing to the next one. Questions regarding the differences between these operators frequently arise during interviews. If asked about ordering, simply refer to concatMap. Here’s a straightforward example:

val first = BehaviorSubject.create<String>()

val second = BehaviorSubject.create<String>()

@SuppressLint("CheckResult")

fun main() {

first.concatMap {

mapTo(it)

}

.subscribe { println(it) }

first.onNext("1")

second.onNext("a")

first.onNext("2")

second.onNext("b")

}

fun mapTo(firstStr: String): Observable<String> {

return second.map {

firstStr + it

}

}

This code will output:

1a

1b

As shown, it never outputs 2 since the inner Observable second never completes. If we modify the code slightly:

val first = BehaviorSubject.create<String>()

val second = Observable.just("a", "b")

@SuppressLint("CheckResult")

fun main() {

first.concatMap {

mapTo(it)

}

.subscribe { println(it) }

first.onNext("1")

first.onNext("2")

}

Now it will print:

1a

1b

2a

2b

This time, 2 is printed because the second Observable completes after emitting a and b, allowing the subscription to proceed to the next emission.

Section 1.2: Exploring switchMap

The switchMap operator behaves differently; it unsubscribes from the inner Observable whenever a new item is emitted from the source Observable. Let’s see how this works in practice:

val first = BehaviorSubject.create<String>()

val second = BehaviorSubject.create<String>()

@SuppressLint("CheckResult")

fun main() {

first.switchMap {

mapTo(it)

}

.subscribe { println(it) }

first.onNext("1")

second.onNext("a")

first.onNext("2")

second.onNext("b")

}

fun mapTo(firstStr: String): Observable<String> {

return second.map {

firstStr + it

}

}

This prints:

1a

2a

2b

Here, when the source Observable emits 2, it unsubscribes from the inner Observable, leading to the outputs of 2a and 2b. Only the latest emission from the inner Observable is retained, discarding earlier ones.

To illustrate this further:

val second = BehaviorSubject.create<String>()

@SuppressLint("CheckResult")

fun main() {

first.switchMap {

mapTo(it)

}

.subscribe { println(it) }

first.onNext("1")

second.onNext("a")

second.onNext("b")

first.onNext("2")

second.onNext("c")

}

fun mapTo(firstStr: String): Observable<String> {

return second.map {

firstStr + it

}

}

The output will be:

1a

1b

2b

2c

As demonstrated, 1a and 1b are printed, but 2a is missing because a was discarded when 2 was emitted.

Now, let's slightly adjust the scenario:

val first = BehaviorSubject.create<String>()

val second = Observable.just("a", "b")

@SuppressLint("CheckResult")

fun main() {

first.switchMap {

mapTo(it)

}

.subscribe { println(it) }

first.onNext("1")

first.onNext("2")

}

This will print:

1a

1b

2a

2b

Finally, adding a delay provides an interesting twist:

val first = BehaviorSubject.create<String>()

val second = Observable.just("a", "b").delay(1, TimeUnit.SECONDS)

@SuppressLint("CheckResult")

fun main() {

first.switchMap {

mapTo(it)

}

.subscribe { println(it) }

first.onNext("1")

first.onNext("2")

Thread.sleep(2000)

}

The output will be:

2a

2b

Here, 1 is never printed due to the 1-second delay, which allows 2 to be emitted first. As a result, only 2a and 2b are displayed.

Note: Avoid using Thread.sleep in production code; this is solely for demonstration purposes.

In this post, I aimed to clarify the distinctions and applications of concatMap and switchMap. I’ve presented various use cases to highlight their behavior across different scenarios. I hope this sheds light on their functionalities for you.

Support with a clap if you found this post helpful!

The first video titled "switchMap vs concatMap vs mergeMap ... Oh My!" offers a detailed exploration of these operators with practical examples, helping to solidify your understanding.

The second video, "Map, switchMap, mergeMap, flatMap, concatMap, exhaustMap in RxJS - what is the difference?" delves into the differences among various mapping operators in RxJS, providing insights that can enhance your programming skills.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Elevate Your Obsidian Experience: Discover New Plugins

Explore innovative Obsidian plugins designed to enhance note-taking and productivity, offering a range of features for a customized experience.

# Simplifying Transfer Learning with PyTorch's New Multi-Weight API

Discover how PyTorch's new API simplifies transfer learning, making it easier to fine-tune neural networks for your specific needs.

# The Rain Dilemma: Exploring Mathematical Reasoning in Nature

This article delves into the famous rain problem, illustrating the significance of mathematical reasoning through real-life scenarios.

Unusual Behaviors That Surface When You're Infatuated

Discover the odd things people often do when they fall in love, from analyzing every gesture to obsessively checking their phones.

Unlocking Arnold Schwarzenegger's Timeless Muscle-Building Wisdom

Discover essential muscle-building tips from Arnold Schwarzenegger that anyone can follow for effective results.

The Electric Vehicle Charging Landscape: What Lies Ahead

Explore the evolving dynamics of electric vehicle charging and its potential impact on prices and accessibility.

Effective Techniques for Anxiety Relief Through Jacobson's Method

Explore Jacobson's progressive relaxation technique for effective anxiety management, enhancing both body and mind wellness.

# Reignite Your Creative Spark: Strategies to Overcome Blocks

Discover effective strategies to overcome creative blocks and unlock your creativity.