持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
什么是异步流?
异步流,即异步返回多个计算好的值(挂起函数只返回一个值)。
流是一种类似于序列的冷流,在每次收集的时候启动。即流的发射由collect()触发。示例:
//返回一个流,不需要挂起
fun simple(): Flow<Int> = flow { //流构建器
for (i in 1..4) {
delay(100)
emit(i) //发射值
}
}
fun main() = runBlocking {
simple().collect { //收集值
value -> "simple value:$value".println()
}
}
flow{...}构建器,构建块中间的代码可以挂起- 返回流的函数不需要带suspend
- 流使用
emit()发射值,使用collect()收集值
流的超时取消并停止执行
fun simple3(): Flow<Int> = flow { //流构建器
for (i in 1..4) {
"Emitting $i".println()
delay(100)
emit(i) //发射值
}
}
fun main() = runBlocking<Unit> {
withTimeoutOrNull(250){ //超时250ms便取消
simple().collect { value -> " $value".println() }
}
"Done".println()
}
结果: Emitting 1 1 Emitting 2 2 Emitting 3 Done
流构建器
除了使用flow{}构建流,还可以使用flowOf(vararg elements:T) 定义流集,asFlow()扩展函数可将整数区间、各种集合和序列转化为流
flowOf("apple","pear","banner","watermelon").collect { value -> println(value) }
(1..4).asFlow().collect { value -> " $value".println() }
arrayOf(1.44,5.56,3.14159).asFlow().collect { value -> " $value".println() }
arrayListOf("apple","pear","banner","watermelon").asFlow().collect { value -> " $value".println() }
流操作符
- 过渡流操作符应用于上游流,返回下游流。
filter过滤操作符:根据规则过滤上游值,结果以布尔值表示map映射操作符:以上游值为参,计算返回下游值transform转换操作符:可以实现filter或map,可以直接发送任意值任意次数 以获取整数区间内奇数的计算结果为例子:
(1..5).asFlow() //将整数区间转化为流
.filter { request -> request % 2 != 0 } //过滤出奇数
.map { request -> testFlow.performRequest(request) } //映射出结果
.transform { response -> //transform 发送两次值
emit(response)
emit("test transform $response")
}
.collect { response -> println(response) } //收集流
response 1
test transform response 1
response 3
test transform response 3
response 5
test transform response 5
- 限长操作符
take(count:Int):当流个数超过count时将抛出异常,流构建块需要通过try catch捕获异常
(1..10).asFlow().take(5).collect { value ->
print(value)
}
12345
- 末端流操作符
collect:收集所有的值,按顺序响应每一个值;toList/toSet:转化为各种集合;first:获取流的第一个值;
val value = (1..10).asFlow().take(5).first()
println("value:$value")
value:1
single:发射单个值,如果有多个值会抛出异常;reduce/fold:累加操作符,将流规约到单个值,用于所有值的链式操作,fold带一个初始值。如10的阶乘:
//创建流
val flow = (1..10).asFlow()
//计算10的阶乘,value是当前上游值,accumulator是之前的运算结果
val reduce_result = flow.reduce { accumulator, value -> accumulator * value }
//带上初始值0
val flod_result = flow.fold(0) { acc, value -> acc * value }
"reduce_result:$reduce_result".println()
"flod_result:$flod_result".println()
reduce_result:3628800
flod_result:0