【问题标题】:How to split a Kotlin flow into 2 flows?如何将 Kotlin 流拆分为 2 个流?
【发布时间】:2020-01-08 11:28:07
【问题描述】:

我正在尝试学习协程,但我仍然遇到一些基本问题。 我有一个发出一系列项目的流,我想将流分成 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 协程流程复制这一点?提前致谢。

【问题讨论】:

  • .filter {}.forEach {} 有什么问题?
  • 如果您正在尝试学习协程,请暂时忘记Flows。学习协程,然后跳转到流

标签: android kotlin kotlin-coroutines


【解决方案1】:

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 取代。)

【讨论】:

    【解决方案2】:

    你用 Rx 做的事情在 Kotlin 流 中是不可能的,因为在你的例子中 share() 将创建一个 hot observable 并且 Kotlin 中的流本质上是

    您可以改用 Channel,因为它们代表 Kotlin 中的热流

    我从 Roman Elizarov 阅读了这篇关于 Cold flows, hot channels 的博文。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多