RxJava如何从Subscription创建Observable

时间:2016-10-29 23:19:11

标签: android rx-java kotlin

我正在寻找一种在subscribe处理结果后创建Observable的方法。

鉴于我有来自productRepo.list()的Observable Retrofit 返回Observable<Response<ProductResponse>>

productRepo
    .list()
    .retry(3)
    .subscribe { response ->
        if (response.isSuccessful) {
            response.body().apply {
                cache.saveProducts(data)
            }
        }
    }

这样做的目的是将结果保存到本地数据库cache。这加上另一个非常类似的调用使用来自API的远程数据填充本地数据库。

完成两个调用后,我想从cache加载数据。

我不想以任何方式将两种观察结合起来。只是想在之后运行一些任务。

我想将此处理作为Rx调用图中的一个单元,以便它同时执行Call1和Call2,并且一旦Call1和Call2完成运行Task3。在这种情况下,最好的方法是什么?我真的更喜欢每个电话的用户是分开的。

这里flatMap是最好的选择吗?

3 个答案:

答案 0 :(得分:3)

.doOnNext()

是您的答案,因为如果是多个,将返回您的最终答案或每个答案。试一试。

答案 1 :(得分:1)

看看Zip。做一些像Observable.zip(firstObservable,secondObservable,..... {Task 3}

答案 2 :(得分:0)

如你所说,

  

我真的更喜欢每个电话的用户是否分开。

假设我们有两个可观察者

val call1 = Observable.from(arrayOf(1,2,3,4,5,6,7,8))

val call2 = Observable.from(arrayOf(2,4,6,8))

如果我们纯粹使用Observable.zip如下,那么两个Call1&amp;只能拥有单个订阅者。 CALL2。

Observable.zip(call1,call2) {c1, c2 -> Pair(c1,c2) }.subscribe(task3Subscriber)

如果我们使用三个单独的订阅者,Call1&amp; Call2流将被触发两次

call1.subscribe(call1Subscriber)

call2.subscribe(call2Subscriber)

Observable.zip(call1,call2) {c1, c2 -> Pair(c1,c2) }.subscribe(task3Subscriber)

因此,我们需要使用.share().cacheWithInitialCapacity(1)来制作技巧

val call1 = Observable.from(arrayOf(1,2,3,4,5,6,7,8))
  .share()
  .cacheWithInitialCapacity(1)

val call2 = Observable.from(arrayOf(2,4,6,8))
  .share()
  .cacheWithInitialCapacity(1)

val task3Signal = Observable.zip(call1,call2){ c1, c2 ->
  c1 + c2
}
call1.subscribe(call1Subscriber)
call2.subscribe(call2Subscriber)
task3Signal.subscribe(task3Subscriber)

您还可以从简单的测试用例中证明/测试您对Rx图的概念。

class SimpleJUnitTest {

  @Test
  fun test(){

    val call1 = Observable.from(arrayOf(1,2,3,4,5,6,7,8))
      .doOnNext { println("call1 doOnNext $it") }
      .share()
      .cacheWithInitialCapacity(1)

    val call2 = Observable.from(arrayOf(2,4,6,8))
      .doOnNext { println("call2 doOnNext $it") }
      .share()
      .cacheWithInitialCapacity(1)

    val task3Signal = Observable.zip(call1,call2){ c1, c2 ->
      println("task3Signal c1:$c1, c2: $c2")
      c1 + c2
    }

    val testSubscriber1 = TestSubscriber<Int>()
    val testSubscriber2 = TestSubscriber<Int>()
    val testSubscriber3 = TestSubscriber<Int>()
    call1.subscribe(testSubscriber1)
    call2.subscribe(testSubscriber2)
    task3Signal.subscribe(testSubscriber3)

    testSubscriber1.assertReceivedOnNext(listOf(1,2,3,4,5,6,7,8))
    testSubscriber2.assertReceivedOnNext(listOf(2,4,6,8))
    testSubscriber3.assertReceivedOnNext(listOf(3,6,9,12))
    testSubscriber1.assertValueCount(8)
    testSubscriber2.assertValueCount(4)
    testSubscriber3.assertValueCount(4)


  }
}

输出:

call1 doOnNext 1
call1 doOnNext 2
call1 doOnNext 3
call1 doOnNext 4
call1 doOnNext 5
call1 doOnNext 6
call1 doOnNext 7
call1 doOnNext 8
call2 doOnNext 2
call2 doOnNext 4
call2 doOnNext 6
call2 doOnNext 8
task3Signal c1:1, c2: 2
task3Signal c1:2, c2: 4
task3Signal c1:3, c2: 6
task3Signal c1:4, c2: 8