Kotlin协程中Flow的常见操作符

一、map&transform转换操作符

map: 对流中的每个元素应用给定的转换函数,并返回转换后的结果流(经过map内的操作后才成为结果流)。如下面为例,将Int类型转换为String类型,但这只是简单的映射函数操作,想要更复杂的处理需要使用transfor.

transform : Flow 中的一个操作符,它允许你对流中的每个元素进行转换,并且每个元素可以映射到一个新的流。而且每个输入元素可以产生零个、一个或多个输出元素(使用emit十分灵活处理,相对map也更加强大)。

二、限长操作符take

take: 从流中获取指定数量的元素,并返回一个新的流。

 三、末端流操作符

如下(参考另一博主视频讲解):

以reduce为例:

四、组合操作符zip

将两个流组合成新的流

五、展平流操作符

在流进行异步接受值序列的时候,可能会 每个值都会触发对另一个值序列的请求。这样形成了一个二维Flow<Flow<Int>>(包含流的流),这时我们需要将其进行展平为单个流以进行下一步处理,集合与序列都拥有 flatten 与 flatMap 操作符来做这件事。然而,由于流具有异步的性质,因此需要不同的展平模式, 为此,存在一系列的流展平操作符。将它展开有以下模式。

1.flatMapConcat连接模式:它们在等待内部流完成之前开始收集下一个值。一个流数据完成后,再收集下一个流数据

    fun requestFlow(i : Int) = flow{
        emit("$i: First")
        delay(500)
        emit("$i: Second")
    }
    @Test
    fun testflatMapMerge() = runBlocking {
        val startTime = System.currentTimeMillis()
        (1..3).asFlow()
            .onEach { delay(100) }
            .flatMapConcat { requestFlow(it) }
            .collect{println("$it at ${System.currentTimeMillis() - startTime} ms")}
    }

2.flatMapMerge并发模式

另一种展平模式是并发收集所有传入的流,并将它们的值合并到一个单独的流,以便尽快的发射值。它由 flatMapMerge 与 flattenMerge 操作符实现。比如下面先将(1.2.3)收集成一个流再合并发给另一个流,这就是并发了同一时间处理(1.2.3)这多个任务(不过将任务集合在一块)

    fun requestFlow(i : Int) = flow{
        emit("$i: First")
        delay(500)
        emit("$i: Second")
    }
    @Test
    fun testflatMapMerge() = runBlocking {
        val startTime = System.currentTimeMillis()
        (1..3).asFlow()
            .onEach { delay(100) }
            .flatMapMerge { requestFlow(it) }
            .collect{println("$it at ${System.currentTimeMillis() - startTime} ms")}
    }

3.flatMapLatest

将每个源流中的元素转换为另一个流,并只关注最新转换出的流。当源流发出新元素时,如果前一个元素对应的流仍在执行,flatMapLatest 会取消前一个元素对应的流,并开始执行新元素对应的流,以确保获取到最新的结果。

   fun requestFlow(i : Int) = flow{
        emit("$i: First")
        delay(500)
        emit("$i: Second")
    }
    @Test
    fun testflatMapMerge() = runBlocking {
        val startTime = System.currentTimeMillis()
        (1..3).asFlow()
            .onEach { delay(100) }
            .flatMapLatest { requestFlow(it) }
            .collect{println("$it at ${System.currentTimeMillis() - startTime} ms")}
    }

 我来解释一下这里,比如1是新元素进来了,这时1的First开始执行,但需要delay(500)才执行1:Second,这个时候2作为新元素进来了,由于1:Second还没开始,还在执行,这个flatMapLatest就会取消前一个元素对应的流,来进行2的,后面一样操作,有同学可能疑问为甚3: Second at 1029 ms会输出,因为在3之后没有新元素进入了,前面的就正常进行即可

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Imagine8877

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值