Flow 取消:37. 构建器中的取消检查

本篇解析 example-flow-37.kt。探讨 flow { ... } 构建器对取消的默认支持。

1. 核心特性:自动检查 ensureActive

为了开发者的便利,flow { ... } 构建器在每次发射值(emit)时,都会自动执行一次 ensureActive() 检测。

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
fun foo(): Flow<Int> = flow { 
for (i in 1..5) {
println("Emitting $i")
emit(i) // 这里会检查协程是否已被取消
}
}

fun main() = runBlocking {
foo().collect { value ->
if (value == 3) cancel() // 收集到 3 时取消协程
println(value)
}
}
  • 结果分析:当发射器尝试发射 4 时,emit 内部检测到协程已取消,会抛出 CancellationException。因此 4 和 5 永远不会被发射。

2. 开发者感悟

这是一个非常人性化的设计。它意味着即使你在 flow { ... } 里写了一个繁忙的计算循环,只要你还在不断地 emit,这个流就是可以被外部及时取消的。

,