I continue playing with Reactor, and now I see compose
operator that behave exactly like flatMap
and I´m wondering if there´s any difference that I don't understand.
@Test
public void compose() throws InterruptedException {
Scheduler mainThread = Schedulers.single();
Flux.just(("old element"))
.compose(element ->
Flux.just("new element in new thread")
.subscribeOn(mainThread)
.doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName())))
.doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName()))
.subscribe(System.out::println);
Thread.sleep(1000);
}
@Test
public void flatMapVsCompose() throws InterruptedException {
Scheduler mainThread = Schedulers.single();
Flux.just(("old element"))
.flatMap(element ->
Flux.just("new element in new thread")
.subscribeOn(mainThread)
.doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName())))
.doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName()))
.subscribe(System.out::println);
Thread.sleep(1000);
}
This two examples behave and return the same result.
Regards.
An excellent explanation by Dan Lew:
The difference is that compose()
is a higher level abstraction: it operates on the entire stream, not individually emitted items. In more specific terms:
compose()
is the only way to get the originalObservable<T>
from the stream. Therefore, operators that affect the whole stream (likesubscribeOn()
andobserveOn()
) need to usecompose()
.In contrast, if you put
subscribeOn()
/observeOn()
inflatMap()
, it would only affect theObservable
you create inflatMap()
but not the rest of the stream.compose()
executes immediately when you create theObservable
stream, as if you had written the operators inline.flatMap()
executes when itsonNext()
is called, each time it is called. In other words,flatMap()
transforms each item, whereascompose()
transforms the whole stream.flatMap()
is necessarily less efficient because it has to create a newObservable
every timeonNext()
is called.compose()
operates on the stream as it is. If you want to replace some operators with reusable code, usecompose()
.flatMap()
has many uses but this is not one of them.