Flow 契约与安全
异常透明性 (Exception Transparency)
Flow 必须对下游异常透明。 这意味着,collect { ... } 中的代码抛出的异常,不能被 flow { ... } 内部的 try-catch 捕获。
kotlin
// ❌ 违规代码
flow {
try {
emit(1)
} catch (e: Exception) {
// 这会捕获下游 collect 中的异常!
// 导致下游无法正常传播错误,也无法响应取消。
println("Caught downstream error: $e")
}
}正确做法:只捕获上游逻辑的异常。
kotlin
flow {
try {
val data = loadData() // 若这里出错,catch 会捕获
emit(data)
} catch (e: Exception) {
emit(fallbackData) // ✅ 仅处理上游错误
}
}并发发射:channelFlow
flow { ... } 是串行的。如果你需要在流内部启动多个协程同时发射数据,必须使用 channelFlow。
kotlin
fun mergedData(): Flow<Data> = channelFlow {
// 两个子协程并发运行
launch { send(apiA.fetch()) }
launch { send(apiB.fetch()) }
}上下文检查 (Context Preservation)
Flow 库在运行时会通过 SafeCollector 检查上下文。 如果 emit 发生的线程与 collect 时的线程不一致(且没有使用 flowOn 声明),会直接抛出 IllegalStateException。