摘抄自 Kotlin 语言官网文档,为的是列出相关操作符,方便自己后期查看
点我跳转 Kotlin 官网文档 Flow
目录
Flow 是什么?
挂起函数可以异步的返回单个值,但是该如何异步返回多个计算好的值呢?这正是 Kotlin 流(Flow)的用武之地。
创建Flow
构建中,不允许 withContext 修改上下文
flow{}
fun simple(): Flow<Int> = flow {
// 流构建器
for (i in 1..3) {
delay(100) // 假装我们在这里做了一些有用的事情
emit(i) // 发送下一个值
}
}
flowOf(1,2,3)
.asFlow()
集合与序列转换为流
emit
发射值。
collect
收集值,构造器内的代码,直到被收集的时候才会运行。
simple().collect{
it-> println(it) }
打印:
1
2
3
取消
withTimeoutOrNull(250)
250毫秒后超时自动取消。
withTimeoutOrNull(250) {
// 在 250 毫秒后超时
simple().collect {
value -> println(value) }
}
println("Done")
转换
map
转换成我们想要的数据。
fun main() = runBlocking<Unit> {
(1..3).asFlow() // 一个请求流
.map {
"number: $it" }
.collect {
response -> println(response) }
}
打印:
number: 1
number: 2
number: 3
transform
可以发射任意值任意次。
fun main() = runBlocking<Unit> {
(1..3).asFlow() // 一个请求流
.transform {
request ->
emit("Making request $request")
emit(performRequest(request))
}
.collect {
response -> println(response) }
}
限长操作符
take
在流触及相应限制的时候将它的执行取消
fun numbers(): Flow<Int> = flow {
try {
emit(1)
emit(2)
println("This line will not execute")
emit(3)
emit(4)
} finally {
println("Finally in numbers")
}
}
fun main() = runBlocking<Unit> {
numbers()
.take(2) // 只获取前两个
.collect {
value -> println(value) }
}
打印:
1
2
This line will not execute
3
Finally in numbers
末端操作符
toList、toSet
转换为需要的集合
first、single、fold
后续再试验
reduce
将流规约到单个值
fun main() = runBlocking<Unit> {
val sum = (1..5).asFlow()
.map {
it * it } // 数字 1 至 5 的平方
.reduce {
a, b -> a + b } // 求和(末端操作符)
println(sum)
}
launchIn
使用 launchIn 替换 collect 我们可以在单独的协程中启动流的收集,这样就可以立即继续进一步执行代码。
// 模仿事件流
fun events(): Flow<Int> = (1..3).asFlow().onEach {
delay(100)