第 6 课2026.07.22
一次网络请求通常返回一个结果,适合使用 suspend;行情、数据库列表、登录状态等数据会持续变化,更适合使用 Flow。KMP 可以在共享层定义数据流,再由 Android 和 iOS 观察同一套业务数据。
第 6 课:用 Flow 表达共享数据流
- 日期:2026-07-22
- 课程序号:06
- 知识点:在
commonMain中使用Flow连续发送数据
用途
一次网络请求通常返回一个结果,适合使用 suspend;行情、数据库列表、登录状态等数据会持续变化,更适合使用 Flow。KMP 可以在共享层定义数据流,再由 Android 和 iOS 观察同一套业务数据。
核心概念
suspend fun load(): T:完成一次异步任务,返回一个结果。fun observe(): Flow<T>:随着时间推移,可以连续发送多个结果。emit(value):向数据流发送一个值。collect { value -> ... }:订阅并处理每个值,必须在协程中调用。- 普通
flow {}是冷流:没有收集者时不会执行,每个收集者都会独立启动一次。
示例代码
本课沿用上一课已经加入 commonMain 的 kotlinx-coroutines-core 依赖。
commonMain/PriceRepository.kt:
kotlin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
class PriceRepository {
fun observePrices(): Flow<Double> = flow {
val prices = listOf(10.0, 10.5, 10.2)
for (price in prices) {
emit(price)
delay(500)
}
}
}调用方需要在自己的协程作用域中收集:
kotlin
lifecycleScope.launch {
PriceRepository().observePrices().collect { price ->
println("最新价格:$price")
}
}输出顺序为:
text
最新价格:10.0
最新价格:10.5
最新价格:10.2收集协程被取消时,delay 和数据流也会一起取消,因此平台调用层仍然负责把收集过程绑定到正确的生命周期。
5 分钟练习
写一个 observeLoginState(): Flow<Boolean>,依次发出 false 和 true,两次发送之间等待 300 毫秒。
参考答案
kotlin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
fun observeLoginState(): Flow<Boolean> = flow {
emit(false)
delay(300)
emit(true)
}调用方可以用 collect { isLoggedIn -> ... } 接收每次状态变化。这里的数据源决定真实状态,UI 只负责渲染收集到的结果。
与上一课的联系
上一课用 suspend 表示一次异步操作;本课把协程扩展为连续数据流。记住选择标准:只需要一个结果时用 suspend,需要观察多个变化时用 Flow。