Skip to content

自定义 Flow 操作符实战

源:Flow 扩展参考

基础原语:transform

所有复杂的中间操作符(如 filter, map)最终都基于 transformcollect

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)