【问题标题】:Kotlin Flow On Android: Launch and Merge subflows from ParentAndroid 上的 Kotlin Flow:从父级启动和合并子流
【发布时间】:2020-06-10 15:03:08
【问题描述】:
我正在从数据库中加载一个 Flow>。基于此结果,我想将每个元素 a 与另一个数据库调用转换为 Pair。
所以基本上是这样的:
dao.getElementAList().map { list ->
list.map {elementA -> Pair(it,dao.call2(elementA)) }
}
调用 2 还返回一个带有 ElementB 的流。返回类型必须是 List>。
如何使用 Kotlin Flow API 实现这一目标?
【问题讨论】:
标签:
android
kotlin
rx-java2
kotlin-flow
【解决方案1】:
先决条件
分级
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.7")
类/接口
interface Database {
fun getElementAList(): Flow<List<Element>>
fun call2(element: Element): Flow<Call2>
}
class DatabaseImpl : Database {
override fun getElementAList(): Flow<List<Element>> {
return flowOf(listOf(Element("1"), Element("2"), Element("3")))
}
override fun call2(element: Element): Flow<Call2> {
return listOf(Call2("c1")).asFlow()
}
}
data class Element(val s: String) {}
data class Call2(val s: String) {}
解决方案
dao.getElementAList()
.flatMapConcat { it.asFlow() }
.flatMapMerge { e -> dao.call2(e).map { c -> e to c } }
注意:结果是流式传输的,不会立即作为列表发出。一次调用失败,全部失败。
测试
@ExperimentalCoroutinesApi
@FlowPreview
@Test
fun sdfdsf() {
val dao = DatabaseImpl()
runBlockingTest {
val result = dao.getElementAList()
.flatMapConcat { it.asFlow() }
.flatMapMerge { e -> dao.call2(e).map { c -> e to c } }
.toList(mutableListOf())
assertThat(result)
.containsExactly(
Element("1") to Call2("c1"),
Element("2") to Call2("c1"),
Element("3") to Call2("c1")
)
}
}