自定义 Flow 操作符实战
基础原语:transform
所有复杂的中间操作符(如 filter, map)最终都基于 transform 或 collect。
kotlin
// 自定义操作符:只发射正数,且放大 10 倍
fun Flow<Int>.positiveX10(): Flow<Int> = transform { value ->
if (value > 0) {
emit(value * 10)
}
}安全准则
1. 协作式取消
Flow 操作符默认不会自动检查取消(除非它发射了值)。如果你的操作符包含耗时的循环或计算,必须手动检查。
kotlin
fun <T> Flow<T>.heavyWork(): Flow<T> = flow {
collect { value ->
// ✅ 必须检查,否则无法响应 cancel()
currentCoroutineContext().ensureActive()
val result = heavyCalculation(value)
emit(result)
}
}2. 上下文一致性
严禁在操作符内部使用 withContext 切换线程。这会破坏下游用户的预期(以为流运行在指定线程,结果被你偷偷切了)。
kotlin
// ❌ 错误:内部写死 IO 线程
fun Flow<Int>.badOp() = flow {
withContext(Dispatchers.IO) { emit(1) }
}
// ✅ 正确:交给用户决定,或者使用 flowOn 整体切换
fun Flow<Int>.goodOp() = flow {
emit(1)
}.flowOn(Dispatchers.IO)