breakline
breakline

Reputation: 6073

How to chain two subscriptions with RxAndroid without flatmap?

I have a chain of events kind of like: "load something - show it - store it". Where showing it and storing it of course happens at the same time (store it in the background while showing it to the user)

Something like this:

myVideoService.getVideo(id)
   .compose(applySchedulers())
   .subscribe((video) -> {
      showVideo(video);
      myVideoService.storeVideo(video).subscribe();
   }, Throwable::printStackTrace)

How could I make this line:

myVideoService.storeVideo(video).subscribe();

part of the original observable? I'd like to run this observable in the background but if I use flatMap this will happen before showing the video, blocking it basically. Even if its not much time I still dont like this concept:

myVideoService.getVideo(id)
   .compose(applySchedulers())
   .flatMap((video) -> myVideoService.storeVideo(video))
   .subscribe((video) -> {
      showVideo(video);
   }, Throwable::printStackTrace)

This would make showVideo after the storing is finished, while ideally this should go side by side

Any other ways to do this where showing and storing the video dont block each other?

Upvotes: 1

Views: 141

Answers (2)

MatBos
MatBos

Reputation: 2390

One way to get trully parallel execution of save and show is like this. Create a PublishSubject, to which add two subscriptions, one for playing the video and one for saving it somewhere(myVideoService.storeVideo(video).subscribe()). Take your original myVideoService.getVideo(id) call and subscribe the subject to it.

This way you will end up with two parallel operations.

PublishSubject subject = PublishSubject.create();
subject
    .doOnNext(video -> myVideoService.storeVideo(video))
    .subscribe();

subject
    .subscribe(this::showVideo);

myVideoService.getVideo(id).subscribe(subject);

With that in mind if save operation is quick there should be no reason to write all that additional code over @akarnokd solution.

Upvotes: 0

akarnokd
akarnokd

Reputation: 69997

The problem is that you apply the schedulers before the flatMap and thus the flatMap evaluates on the main thread. You have to break up the applySchedulers or move flatMap before it:

myVideoService.getVideo(id)
  .subscribeOn(Schedulers.io())                   // <----------------------------------
  .flatMap((video) -> myVideoService.storeVideo(video))
  .observeOn(AndroidSchedulers.mainThread())      // <----------------------------------
  .subscribe((video) -> {
      showVideo(video);
  }, Throwable::printStackTrace);

Upvotes: 2

Related Questions