3

Say I have 2 Observables (A & B) that are essentially network calls (using Retrofit to give context).

The current flow of the app is as follows:

  • A & B are kicked off at about the same time (asynchronously).
  • B is executed 0 or more times on user interaction

I have 3 different scenarios that I want to listen for given these 2 observables/api calls.

  1. I want to know immediately when Observable A completes
  2. I want to know immediately when Observable B completes
  3. I want to know when both have completed

First off, is this a good use case for RxJava?

I know how to do each scenario individually (using zip for the last), though I don't know how to do all of them simultaneously.

If I subscribe to Observable A, A begins. If I subscribe to B, B begins. If A & B complete before I subscribe to zip(a, b), I could miss the event and never actually see this complete, right?

Any general guidance would be appreciated. My RxJava knowledge is pretty thin :P

loeschg
  • 29,961
  • 26
  • 97
  • 150

1 Answers1

5

You can achieve this using three different observable, one for each of your case.

As you'll have to share states between each observables, you'll have to convert retrofit cold observables to hot observable. (see here for more information on this topic)

ConnectableObservable a = service.callA().publish(); 
ConnectableObservable b = service.callB().publish();

a.subscribe((e) -> { /* onNext */ }, (ex) -> {/* onError */},  () -> {/* when A is completed */ });
b.subscribe((e) -> { /* onNext */ }, (ex) -> {/* onError */},  () -> {/* when B is completed */ });
a.mergeWith(b).subscribe((e) -> { /* onNext */ }, (ex) -> {/* onError */},  () -> {/* when A and B are completed */ });

a.connect(); // start subscription to a
b.connect(); // start subscription to b

Do not share an object between onCompleted methods or you'll have to deal with concurrencies issues.

dwursteisen
  • 11,435
  • 2
  • 39
  • 36
  • Awesome, this was really helpful. Do you mind expanding a bit on the concurrency issues I might run in to? If I observe all of them on the same thread, is this still a concern? I'd think either A or B would complete first, followed by A+B. – loeschg Dec 10 '14 at 17:14
  • Observable a, Observable b and Observable ab (the merged observable from a and b) can be completed in different threads. So, call to onCompleted methods can not be sequencial (contrary to the rx contract). You can read a shared variable named "hello" in a onCompleted method. The next line, you read again the same variable. Value can have change, as another onCompleded method from another observable can have change it. – dwursteisen Dec 11 '14 at 10:47