线程切换与背压处理
Flow 的线程模型是其区别于 RxJava 的显著特征。
flowOn:逆流而上
flowOn 是用于改变上游 (Upstream) 执行上下文的操作符。 它就像一个“截断阀”,只影响在它上方(直到下一个 flowOn)的操作符。
mermaid
graph BT
Emit[emit] -- IO Thread --> Map[map]
Map -- IO Thread --> FlowOn[flowOn(IO)]
FlowOn -- Main Thread --> Collect[collect]kotlin
flow {
// 运行在 IO
emit(fetchData())
}
.map {
// 运行在 IO
process(it)
}
.flowOn(Dispatchers.IO) // ⭐️ 切换点
.collect {
// 运行在 Main (启动协程的上下文)
updateUi(it)
}启动不收集:launchIn
launchIn 是一个快捷方式,用于在指定 Scope 中自动启动 collect。它返回一个 Job,允许你随时手动取消流。
kotlin
// 传统写法:嵌套地狱
viewModelScope.launch {
flow.collect { ... }
}
// 优雅写法
flow.onEach { ... }
.launchIn(viewModelScope)默认背压
Flow 是同步的。这意味着默认情况下,发射和收集是按顺序执行的(发射一个 -> 收集一个)。 只有使用了 flowOn 或 buffer 等操作符后,才会引入并发缓冲,从而产生“背压”现象。