RxJava - 多播可完成的结果

时间:2018-01-12 13:10:41

标签: java android rx-java2 rx-android

我有一个Completable,它按顺序发出两个网络请求(类似握手)。可以在我的代码中的许多地方触发此操作。我想要的是:

  • 当已经完成它的工作时多次调用完成时,它不应该重新开始,而是只进行一次"握手",然后返回"的onComplete"所有订阅者的活动
  • 当第二次调用completable,但它已经完成其工作或之前遇到错误时,应该重新启动它(它不应该只是缓存以前的结果)。

我尝试应用不同的解决方案,包括this one,但出于某种原因,我仍然可以看到并行发出多个请求。

public Completable prepareMuticastCompletable() {
  return networkService.makeHandshake() // Completable, makes two network requests
      // transform it into ConnectableObservable
      .toObservable()
      .replay()
      // stay connected as long as there are any subscribers
      .refCount()
      // transform it back to Completable
      .ignoreElements()
      .doOnSubscribe(disposable -> Log.d("Test", "subscribe"));
}

如果我尝试多次订阅此完整版,我希望看到多个" onComplete"事件,但动作只执行一次(两个HTTP请求)。

D/Test: subscribe
D/Test: subscribe
D/OkHttp: --> GET https://.../startHandshake
D/OkHttp: --> GET https://.../startHandshake
D/OkHttp: <-- 200 OK https://.../startHandshake (503ms, 184-byte body)
D/OkHttp: <-- 200 OK https://.../startHandshake (508ms, 184-byte body)
D/OkHttp: --> POST https://.../finishHandshake (151-byte body)
D/OkHttp: --> POST https://.../finishHandshake (151-byte body)
D/OkHttp: <-- 200 OK https://.../finishHandshake (151ms, 196-byte body)
D/OkHttp: <-- 200 OK https://.../finishHandshake (150ms, 196-byte body)
D/OkHttp: done 2
D/OkHttp: done 1

我错过了什么?我应该使用其他RxJava方法吗?

修改 订阅(用于测试)如下所示:

private Completable prepareCompletable() {
  return prepareMuticastCompletable()
    .andThen(someOtherNotRelevantCompletable()); 
}

//...

prepareCompletable()
  .doOnComplete(() -> Log.d("OkHttp", "done 1"))
  .subscribe();
prepareCompletable()
  .doOnComplete(() -> Log.d("OkHttp", "done 2"))
  .subscribe();

1 个答案:

答案 0 :(得分:2)

你必须缓存冷序列并以某种方式重用它:

Completable c = prepareCompletable()

c.doOnComplete(() -> Log.d("OkHttp", "done 1"))
    .subscribe();

c.doOnComplete(() -> Log.d("OkHttp", "done 2"))
    .subscribe();

但请注意,如果第一个响应很快,您仍然可以获得双重呼叫。