我正在尝试学习协程,但仍然存在一些基本问题。 我有一个发出一系列项目的流,我想将流分成2个流。这就是我用RxJava编写的方式:
val list = Flowable.just(1..6).share()
val even = list.filter { it % 2 == 0 }.subscribe { println(it) } // 2, 4, 6
val odd = list.filter { it % 2 == 1 }.subscribe { println(it) } // 1, 3, 5
我该如何用Kotlin协程流复制它?预先感谢。
答案 0 :(得分:3)
一系列sharing operators(以及a hot SharedFlow
)正在简化您正在寻找的工作流程(使用Kotlin Flows)。
同时,流量自然是冷的(因此您不能真正地按原样共享),但是它们仍然可以共享热源来满足您的需求。我提供了有关如何in this answer的详细信息。
简而言之,最终结果如下:
val original: Flow<String> = flowOf("aap", "noot", "mies", "wim", "zus","jet","weide","does")
// create an implicit hot BroadcastChannel, shared between collectors
// so that they each get all elements (which are each produced only once)
val sharedFlow = original.broadcastIn(scope).asFlow()
// create derived cold flows, which will subscribe (on collect) to the
// same hot source (BroadcastChannel)
val flow1 = sharedFlow.filter { it.length == 4 }
val flow2 = sharedFlow.filter { it.length == 3 }.map { it.toUppercase() }
flow1.collect { it -> println("Four letter: ${it}") }
flow2.collect { it -> println("Three letter: ${it}") }
(很快将由SharedFlow
代替。)
答案 1 :(得分:2)
对于科特林流量,您对Rx所做的操作几乎是不可能的,因为在您的示例中,share()
将创建可热观测,而科特林的流量自然而然冷。
您可以改用Channel
,因为它们代表了Kotlin中的热门流。
我从 Roman Elizarov 阅读了有关Cold flows, hot channels的博客文章。
答案 2 :(得分:1)
@shkschneider是完全正确的。这是完整的示例:
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking
@ExperimentalCoroutinesApi
fun main() {
runBlocking {
val flow = flow {
for (i in 1..10) {
emit(i)
}
}
flow.filter { it % 2 == 0 }.collect { println(it) } // prints 2 4 6 8 10
flow.filter { it % 2 != 0 }.collect { println(it) } // prints 1 3 5 7 9
}
}