Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava 2 - Observable.flatMapSingle clarification

I did an RxJava2 experiment consisting of the following steps:

  1. Create an Observable from a ListA of Objects.
  2. Use flatMapSingle() to map each item emitted by the Observable, to a SingleSource. Inside flatMapSingle(), an asychronous operation is executed for each item emitted by the Observable.
  3. Collected all items in a ListB, with Observable.toList()

Result: ListB has its items in different order than ListA due to the asynchronous operation.

So, it seems that flatMapSingle() works like flatMap() in the sense that it uses the merge operator and does not guarantee that the order of the elements will be preserved.

Is my conclusion correct? Documentation did not cover me and discussions about this behavior are nonexistent.

like image 232
Ευάγγελος Μπίλης Avatar asked Nov 08 '17 09:11

Ευάγγελος Μπίλης


People also ask

What is flatMapSingle?

Use flatMapSingle() to map each item emitted by the Observable, to a SingleSource. Inside flatMapSingle(), an asychronous operation is executed for each item emitted by the Observable. Collected all items in a ListB, with Observable. toList()

How do I convert Observable to single RxJava?

Transforming Single to Observable is simple, as Single satisfies Observable's contract. Just call single. toObservable() and you're good.

What is flatMapIterable?

flatMapIterable : Maps the values of the upstream source into Iterable s and iterates each of them one after the other. In other words, it merges dynamically generated pull sources. You can express flatMapIterable as flatMap(Observable::fromIterable) or concatMap(Observable::fromIterable) .

What is FlatMap RxJava?

The FlatMap operator transforms an Observable by applying a function that you specify to each item emitted by the source Observable, where that function returns an Observable that itself emits items. FlatMap then merges the emissions of these resulting Observables, emitting these merged results as its own sequence.


1 Answers

flatMap doesn't guarantee ordering as @akarnokd mentioned in the comment.

If you want to guarantee ordering you can use concatMap but it allows you to only concatenate with inner Observable. It seems there is no version of concatMapSingle in both RxJava1 and RxJava2. You, however, can workaround it by converting inner Single to Observable using toObservable() by yourself and use it with concatMap like this (code written in Kotlin).

Observable
    .fromIterable(listA)
    .concatMap { single.toObservable() }
    .toList() // Items in the list has same order of listA

Note that there is also concatMapEager that will eagerly subscribe to an inner Observable (or Single in the above example) that may help improve parallelize tasks.

like image 189
onelaview Avatar answered Sep 22 '22 09:09

onelaview