Skip to content

线程切换与背压处理

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 是同步的。这意味着默认情况下,发射和收集是按顺序执行的(发射一个 -> 收集一个)。 只有使用了 flowOnbuffer 等操作符后,才会引入并发缓冲,从而产生“背压”现象。