【Kotlin 协程】Flow 流组合 ( Flow#zip 组合多个流 | 新组合流的元素收集间隔与被组合流元素发射间隔的联系 )
2023-06-13 09:18:06 时间
文章目录
一、Flow 流组合
1、Flow#zip 组合多个流
调用 Flow#zip 函数 , 可以将两个 Flow 流合并为一个流 ;
Flow#zip 函数原型 :
/**
* 将来自当前流(' this ')的值压缩到[其他]流,使用提供的[transform]函数应用到每对值。
* 在剩下的流上调用一个流完成和取消时,生成的流就会完成。
*
* 可以用下面的例子来演示:
* ```
* val flow = flowOf(1, 2, 3).onEach { delay(10) }
* val flow2 = flowOf("a", "b", "c", "d").onEach { delay(15) }
* flow.zip(flow2) { i, s -> i.toString() + s }.collect {
* println(it) // Will print "1a 2b 3c"
* }
* ```
*
* ### 缓冲
*
* 上游流在同一协程中按顺序收集,而不进行任何缓冲
* [other]流被并发收集,就像使用' buffer(0) '一样。参见[buffer]操作符中的文档
* 为解释。您可以根据需要使用对[buffer]操作符的额外调用,以获得更多并发性。
*/
public fun <T1, T2, R> Flow<T1>.zip(other: Flow<T2>, transform: suspend (T1, T2) -> R): Flow<R> = zipImpl(this, other, transform)
代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
val numFlow = (1..3).asFlow()
val strFlow = flowOf("One", "Two", "Three")
// 合并两个 Flow 流
numFlow.zip(strFlow) { num, str ->
"num = $num, str = $str"
}.collect {
println(it)
}
}
}
}
执行结果 :
2022-12-26 16:39:29.428 30002-30002/kim.hsl.coroutine I/System.out: num = 1, str = One
2022-12-26 16:39:29.429 30002-30002/kim.hsl.coroutine I/System.out: num = 2, str = Two
2022-12-26 16:39:29.433 30002-30002/kim.hsl.coroutine I/System.out: num = 3, str = Three
2、新组合流的元素收集间隔与被组合流元素发射间隔的联系
假如两个 Flow 流的 元素发射 不同步 , 则 先发射的元素 , 需要等待对应顺序的 后发射的元素到来 ;
在下面的代码中 , numFlow 的发射元素间隔为 100ms , strFlow 发射元素间隔为 1000ms , 则 numFlow 元素收集到之后 , 需要等待 strFlow 元素收集 , 也就是 二者合并后的间隔以 慢的为准 , 合并后的流 发射间隔为 1000ms ;
代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
val numFlow = (1..3).asFlow().onEach { delay(100) }
val strFlow = flowOf("One", "Two", "Three").onEach { delay(1000) }
// 合并两个 Flow 流
numFlow.zip(strFlow) { num, str ->
"num = $num, str = $str"
}.collect {
println(it)
}
}
}
}
执行结果 :
2022-12-26 16:48:43.931 31838-31838/kim.hsl.coroutine I/System.out: num = 1, str = One
2022-12-26 16:48:44.949 31838-31838/kim.hsl.coroutine I/System.out: num = 2, str = Two
2022-12-26 16:48:45.956 31838-31838/kim.hsl.coroutine I/System.out: num = 3, str = Three
相关文章
- Kotlin在协程中使用Select表达式选择最快结果
- 开心档-软件开发入门之Kotlin 基本数据类型
- Kotlin 泛型:基本使用
- 【Kotlin】Kotlin 领域特定语言 DSL 原理 一 ( DSL 简介 | 函数 / 属性扩展 )
- 【Kotlin】扩展函数 ( 扩展函数声明 | 调用方式 | 与成员函数优先级 | 接收者空值处理 )
- 【JetPack】kotlin-android-extensions 插件 ( 视图绑定简单用法 )
- 【错误记录】Kotlin 1.5.0 编译报错 ( 1.5.0 中 Float 不能直接转 Byte 类型 )
- 【错误记录】Kotlin 报错 ( Some kotlin libraries attached to this project were compiled with a newer kotlin )
- 【Kotlin 协程】协程启动 ⑤ ( 协程作用域构建器 | runBlocking 函数 | coroutineScope 函数 | supervisorScope 函数 )
- 【Kotlin 协程】协程异常处理 ② ( SupervisorJob 协程 | supervisorScope 协程作用域构建器函数 )
- 【Kotlin 协程】协程异常处理 ⑤ ( 异常传播的特殊情况 | 取消子协程示例 | 子协程抛出异常后父协程处理异常时机示例 | 异常聚合 | 多个子协程抛出的异常会聚合到第一个异常中 )
- 【Kotlin 协程】Flow 异步流 ⑧ ( 背压概念 | 使用缓冲处理背压问题 | 使用 flowOn 处理背压问题 | 从提高收集元素效率方向解决背压问题 )
- 【Kotlin】类的初始化 ④ ( lateinit 延迟初始化 | ::属性名称.isInitialized 检查属性是否初始化 | lazy 惰性初始化 )
- 【Kotlin】扩展函数 ③ ( 定义扩展文件 | 重命名扩展函数 | Kotlin 标准库扩展函数 )
- kotlin点击事件详解手机开发
- 压缩你的Linux:使用Zip源码(zip源码linux)
- Linux下增加Zip文件的实现方法(linux给zip加文件)
- 文件Linux解压实战:文件ZIP的解压技巧(linux的解压zip)
- Linux下利用Zip命令快速打包文件(linux打包命令zip)
- Linux压缩工具:Zip打包操作(zip打包linux)
- Zip 压缩在 Linux 中的应用(zip压缩linux)
- 探索Linux查看ZIP文件内容的方法(linux查看zip内容)
- Linux解压ZIP文件到指定文件夹的操作方法(linux解压zip到指定文件夹)
- 压缩文件深入挖掘:Linux 系统下解压Zip压缩文件的方法(linux如何解压zip)
- MySQL的ZIP配置简单易学(mysql zip 配置)
- 使用MySQL ZIP文件还原数据库备份的步骤(mysql zip 还原)
- 解压 MySQL Zip 包遇到的问题与解决方法处理大容量数据压缩包(mysql zip 很大)
- 下载 MySQL Zip 版,快捷安装数据库(mysql zip版下载)