Kotlin Flow On Android。从父流发起和合并子流

问题描述 投票:0回答:1

im从数据库中加载一个Flow>。基于这个结果,我想把每个元素a用另一个数据库调用转换为一个Pair。

所以基本上是这样的。

dao.getElementAList().map { list ->
 list.map {elementA -> Pair(it,dao.call2(elementA)) }
}

调用2也返回一个带有ElementB的Flow。返回类型必须是List>。

我如何用Kotlin Flow API实现这个目标?

android kotlin rx-java2 kotlin-flow
1个回答
0
投票

前提条件

Gradle

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 } }

注意:结果是流式的,而不是以List的形式一次性emmmited。如果一个调用失败,所有的调用都会失败。

测试

@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")
                )
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.