第 45 课2026.09.02
避免把连续两次相同操作误当成同一份状态。
第 45 课:状态流与事件流的语义选择
- 日期:2026-09-02
- 课程序号:第 45 课
- 知识点:StateFlow 相等合并与 SharedFlow 重放
用途
避免把连续两次相同操作误当成同一份状态。
核心概念
- StateFlow 始终有当前值,相等值不会再次通知,慢订阅者可能跳过中间状态。
- SharedFlow 可以重复发送相等值,但 replay=0 不向后来订阅者补发历史;它不是持久事件队列。
- 需要当前状态选 stateIn;需共享事件时按消费契约选择 shareIn 的 replay。
最小代码或操作示例
kotlin
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.shareIn
fun shareCount(source: Flow<Int>, scope: CoroutineScope): StateFlow<Int> =
source.stateIn(scope, SharingStarted.WhileSubscribed(), 0)
fun shareClicks(source: Flow<String>, scope: CoroutineScope): SharedFlow<String> =
source.shareIn(scope, SharingStarted.WhileSubscribed(), replay = 0)3~5 分钟练习
判断“当前收藏数量”和“连续两次相同按钮点击”分别更适合哪种流;晚订阅者是否应收到旧点击?
参考答案
kotlin
// 当前收藏数量:StateFlow,始终提供当前状态。
// 两次相同点击:SharedFlow 可表达重复事件。
// replay=0:晚订阅者不收到旧点击;无订阅者时也不保证事件保留。
// 若要求不丢事件,需另行设计持久化和确认消费机制。与上一课的联系
上一课学习 shareIn,第 34 课已学习 stateIn;本课新增相等值与晚订阅行为的选择依据。
参考资料
- 官方文档:状态流与事件流的语义选择(2026-09-02 核对;软件界面以所用版本为准)。