1
votes

So I'm learning RxPy after doing RxJava and RxKotlin for two years. One thing I'm noticing is that certain operators cause crazy interleaving that does not happen in RxJava.

For example, flat_map() will cause emissions to interleave out of order for a simple Observable source.

items = Observable.from_( ("Alpha","Beta","Gamma","Delta","Epsilon"))

items.flat_map(lambda s: Observable.from_(list(s))).subscribe(print)

OUTPUT:

A
l
B
p
e
G
h
t
a
D
a
a
m
e
E
m
l
p
a
t
s
a
i
l
o
n

However, with RxJava or RxKotlin, everything stays sequential and in order.

fun main(args: Array<String>) {
    Observable.just("Alpha","Beta","Gamma","Delta","Epsilon")
        .flatMap {
            Observable.from(it.toCharArray().asIterable())
        }.subscribe(::println)
}

OUTPUT:

A
l
p
h
a
B
e
t
a
G
a
m
m
a
D
e
l
t
a
E
p
s
i
l
o
n

I confirmed that everything is running on the MainThread and there is no weird asynchronous scheduling going on (I think).

Why does RxPy behave this way? I notice that this happens almost with any operator that deals with multiple Observable sources merging together. What exactly is the default Scheduler doing?

Also, why is there no concat_map() in RxPy? I'm getting the impression this is somehow not possible with how the scheduling works...

1
The fact that flatMap happens to respect order in RxJava is an implementation detail, and you should not be relying on it. Use concatMap if you require order to be preserved. - Asad Saeeduddin
Well sure, I guess that's true. I guess that evolves my question to why is concat_map() not implemented in RxPy? Will update question to include this... - tmn

1 Answers

3
votes

As has already been noted, flatMap does not guarantee order. RxPy doesn't implement concat_map as a distinct operator but you can get the same effect using the map and concat_all operators

Observable.from_( ("Alpha","Beta","Gamma","Delta","Epsilon"))\
          .map(lambda s: Observable.from_(list(s)))\
          .concat_all()\
          .subscribe(print)