Search code examples
rx-java2rx-kotlin2

How to avoid multiple mapper calls when using flatMapSingle


Suppose I have a BehaviorProcessor which contains some value v.

Now if I want to asynchronously request some data, which would depend on v I would do it like this:

val res = v.flatMapSingle { asyncRequest(it) }

Now let's log all the invocations of this block (mapper)

val res = v.flatMapSingle {
    println("mapper")
    asyncRequest(it)
}

It will print mapper multiple times, which means asyncRequest is being called multiple times, it seems every time some other dependant stream is being subscribed to

I am trying to avoid multiple mapper invocations (thus avoiding multiple asyncRequest calls).

Is there a way to do so with standard rxjava2 utils?


Solution

  • Use cache() operator. It will cache result of flatMapSingle.

    BehaviorProcessor<String> v = BehaviorProcessor.create();
    Flowable<String> res = v.flatMapSingle(item -> {
        System.out.println("mapper");
        return asyncRequest(item);
        })
            .cache();
    v.onNext("test");
    res.subscribe(s->System.out.println("subscribe1 received: "+ s));
    res.subscribe(s->System.out.println("subscribe2 received: "+ s));
    v.onNext("test2");
    

    Produces

    mapper
    mapper
    subscribe1 received: test async
    subscribe2 received: test async
    subscribe1 received: test2 async
    subscribe2 received: test2 async