【问题标题】:Converting loop with condition into RxJava stream将带条件的循环转换为 RxJava 流
【发布时间】:2018-07-05 07:39:56
【问题描述】:

我有代码在 while 循环中执行阻塞操作(从服务器下载一些数据)。客户不知道每一步要返回多少物品。下载 N 个项目时循环中断。

val n = 10
val list = ArrayList<T>()

while (list.size < n) {
    val lastItemId = list.last()?.id ?: 0
    val items = downloadItems(lastItemId)
    list.addAll(items)
}

downloadItems 执行阻塞 HTTP 调用并返回列表。现在让我们假设downloadItems 发生变化,新的返回类型是Observable&lt;Item&gt;。如何更改代码以使用 RxJava 而不执行类似 blockingGet 的操作?

【问题讨论】:

    标签: android rx-java rx-java2 rx-kotlin rx-kotlin2


    【解决方案1】:

    您可以使用repeatUntil 来实现:

    var totalItems = 0    
    var id = 0
    Observable.fromCallable {
                downloadItems(id)
            }
            .flatMap {
                list ->
                    totalItems += list.size
                    id = list.last()?.id ?: 0
                    Observable.just(list)
            }
            .repeatUntil({totalItems > n})
            .subscribe({result -> System.out.println(result) })
    

    【讨论】:

      【解决方案2】:

      我认为这是一种优雅的方式

      int n = 10;
      Observable.range(0,n)
              .flatMap(i -> downloadItems(i))
              .toList()
              .subscribe(itemsList -> itemsList.forEach(item -> System.out.println(item)));
      

      【讨论】:

      • 这将调用 downLoadItems 10 次。我只想下载 10 个项目。每次调用 downloadItems 可能返回超过 0 个项目,具体项目数量未知。
      • 我发现了和你的问题类似的问题stackoverflow.com/questions/50827046/…
      猜你喜欢
      • 1970-01-01
      • 2021-01-11
      • 2021-03-01
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2017-02-09
      相关资源
      最近更新 更多