前言
StateFlow 是ShareFlow的replay=1,必须有默认值,emit方法永远不会挂起,订阅时总是能够拿到它的最新的一个元素。
fun main() {
runBlocking {
val stateFlow = MutableStateFlow(-1)
launch {
repeat(3) {
delay(10)
println("threadName:${Thread.currentThread().name} emit:$it time:${System.currentTimeMillis()}")
stateFlow.emit(it)
}
stateFlow.collect {
println("threadName:${Thread.currentThread().name} collect:$it time:${System.currentTimeMillis()}")
}
}
}
}
输出:
threadName:Test worker @coroutine#2 emit:0 time:1712719296772
threadName:Test worker @coroutine#2 emit:1 time:1712719296787
threadName:Test worker @coroutine#2 emit:2 time:1712719296803
threadName:Test worker @coroutine#2 collect:2 time:1712719296807
在同一个协程2中进行先emit再collect。则只会collect最后一个数据。
fun main() {
runBlocking {
val stateFlow = MutableStateFlow(-1)
launch {
delay(100)
repeat(3) {
println("threadName:${Thread.currentThread().name} emit:$it time:${System.currentTimeMillis()}")
stateFlow.emit(it)
}
}
launch {
stateFlow.collect {
println("threadName:${Thread.currentThread().name} collect:$it time:${System.currentTimeMillis()}")
}
}
}
}
输出:
threadName:Test worker @coroutine#3 collect:-1 time:1712719030700
threadName:Test worker @coroutine#2 emit:0 time:1712719030810
threadName:Test worker @coroutine#2 emit:1 time:1712719030811
threadName:Test worker @coroutine#2 emit:2 time:1712719030811
threadName:Test worker @coroutine#3 collect:2 time:1712719030811
先collect到默认值-1;在协程2中连续emit 3个值,在协程2 collect只收到最后一个值,中间值全部丢弃了。
fun main() {
runBlocking {
val stateFlow = MutableStateFlow(-1)
launch {
repeat(3) {
delay(10)
println("threadName:${Thread.currentThread().name} emit:$it time:${System.currentTimeMillis()}")
stateFlow.emit(it)
}
}
launch {
stateFlow.collect {
println("threadName:${Thread.currentThread().name} collect:$it time:${System.currentTimeMillis()}")
}
}
}
}
输出:
threadName:Test worker @coroutine#3 collect:-1 time:1712719168577
threadName:Test worker @coroutine#2 emit:0 time:1712719168596
threadName:Test worker @coroutine#3 collect:0 time:1712719168597
threadName:Test worker @coroutine#2 emit:1 time:1712719168612
threadName:Test worker @coroutine#3 collect:1 time:1712719168612
threadName:Test worker @coroutine#2 emit:2 time:1712719168627
threadName:Test worker @coroutine#3 collect:2 time:1712719168627
如果对emit添加10ms延迟,则中间值全部collect到了。
从上面看出StateFlow更适合更新状态(中间值可能丢弃,但是保证最新值能collect到)