Shvalb
Shvalb

Reputation: 1933

How to execute 2 Observables in parallel, ignoring their results and execute next Observable

I have to execute 2 observable in parallel (don't care about their output), and when they both finished -> run another observable.

This is my solution, but I feel there are better ones:

rx.Observable<GameObject> obs1 = ...;
rx.Observable<GameObject> obs2 = ...;

rx.Observable.merge(obs1,obs2).takeLast(1)
.flatMap(mergeObj -> {

    return payoutStrategy.calculatePayout(gameTemplate, gameData);
}).subscribe(results -> { 
...
});

I use merge just in order to invoke the 2 obs's and then 'takeLast(1)' to ignore entering 'flatMap' twice.

This solution is far from being elegant but it works..

Any ideas how to make it better?

Thanks!

Upvotes: 4

Views: 3064

Answers (1)

Dave Moten
Dave Moten

Reputation: 12097

concat is useful for doing something on completion of something else. Because the type of Observable returned by calculatePayout is presumably different you cast the empty stream to its result type:

obs1.mergeWith(obs2)
    .ignoreElements()
    .castAs(Payout.class)
    .concatWith(payoutStrategy.calculatePayout(gameTemplate, gameData))
    .subscribe( ...)

By the way if obs1 and obs2 are not async sources already then you can do this to ensure obs1 and obs2 are run in parallel:

obs1.subscribeOn(scheduler).mergeWith(obs2.subscribeOn(scheduler))
    ...

Depending on what obs2 is doing scheduler might be Schedulers.computation() or Schedulers.io().

For multiple source observables you can also do this:

Observable.just(obs1, obs2, .. , obsN)
    .flatMap(o -> o.subscribeOn(Schedulers.computation())
    .ignoreElements()
    ...

Upvotes: 3

Related Questions