android - 取单对于另一个 Single 的所有元素在 RxKotlin 中
- 在 RxKotlin 中
问题描述
A、B、C 是对象
所有函数调用都对 Rooms DB 进行
此代码片段位于 ViewModel 内
回购 = 存储库
因此,我正在制作一个 android 应用程序(无法提供详细信息),对于特定屏幕,我需要执行以下操作。
我的第一个调用是repo.getInfo,它返回一个Single Observable ListOfA: Single<List<A>>
//执行一些操作
对于 ListOfA 的每个元素,我需要调用另一个函数 repo.getB(A),它返回一个可观察的 ListOfB:Single<List<B>>
//执行一些操作
对于 ListOfB 的每个元素,我需要调用另一个函数 repo.getC(B),它返回一个可观察的 ListOfC:Single<List<C>>
//执行一些操作
获得所需数据后,我需要调用另一个函数来组合数据以显示在 UI 上。
现在我无法让它工作。这是我尝试过的。但是流程在标记为 THIS LINE 的行处停止并跳转到订阅块。对函数的单独调用有效,因此数据不是问题。我对此很陌生,坦率地说,我的深度不够。任何帮助或提示表示赞赏。谢谢
localListOfA = emptyList<A>()
localListOfB = emptyList<B>()
localListOfC = emptyList<C>()
compositeDisposable.add(
getInfo.map{listOfA ->
localListOfA.addAll(listofA)
listOfA.map {elementA -> ////THIS LINE
getB(elementA.id).map{listOfB ->
listOfB.filter {
//some logic to select a few objects
}
}.map { it // filtered list of B
localListofB.addAll(it)
localListOfB.last() //I only need the top element of this list
}.map{elementB ->
getC(elementB.id).map{ listOfC ->
localListOfC.addAll(listOfC)
//do some operations
}
}
}
}
.subscribeOn(DEFAULT_CACHED_SCHEDULERS)
.observeOn(AndroidSchedulers.mainThread())
.doOnError(/*take log*/)
.subscribe{
prepareUi()
}
)
解决方案
您可以将 a 展平List
为Observable
using.flattenAsObservable
getInfo // Single<List<A>>
.doOnSuccess { localListOfA.addAll(it) } // Side effect, adding to localListOfA
.flattenAsObservable { it } // Observable<A>
.flatMapSingle { elementA -> getB(elementA.id) } // Observable<List<B>>
.map { it.filter { true } } // Some logic to select a few objects from B
.doOnNext { localListOfB.addAll(it) } // Side effect, adding to localListOfB
.map { it.last() } // Observable<B>, only the last element
.flatMapSingle { elementB -> getC(elementB.id) } // Observable<List<C>>
.doOnNext { localListOfC.addAll(it) } // Side effect, adding to localListOfC
.flatMapIterable { it } // Observable<C>
现在,您提到您需要以某种方式组合这些数据。在 Rx 中,您可以嵌套链以访问中间数据。例如,如果您有一个返回 a 的调用Single<Foo>
并且您需要Foo
function getBar(foo: Foo): Single<Bar>
,则实现此目的的一种方法如下:
getFoo().flatMap { foo -> // .concatMap, .switchMap
getBar(foo).map { bar ->
// Use both foo and bar
}
}
推荐阅读
- java - 获取模式匹配或 do while 循环中的 try catch 问题,即使输入所需的输入也会导致循环循环
- javascript - 我将如何查找某些 GPU 信息
- android - 如何通过 UIAutomator2 获取活动名称?
- ramda.js - 删除对象中的键列表,该键可能不存在
- python - 按元素对元组数组进行切片
- postgresql - 为不同列中的每个唯一名称选择具有最大值的单行
- python - 为什么 pydirectinput 在 Crossout 中不起作用?
- html - CSS 网格对齐可以由子 React 组件控制吗?
- sql - 在 SQL 输出中需要一个额外的列
- javascript - 如何将 DataTable 中的单个列搜索与服务器端处理一起使用?