在 Kotlin 协程库中,collect
和 collectLatest
都是用于收集 Flow
中发射的数据的方法,但它们在处理数据和响应新数据的方式上有所不同。
collect
collect
是一个挂起函数,用于收集 Flow
中发射的所有数据。它会按顺序处理每一个发射的数据项,直到数据流结束。处理每一个数据项是一个同步操作,只有在处理完当前数据项后,才会开始处理下一个数据项。
示例:
Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking<Unit> {
val flow = flow {
emit(1)
delay(100)
emit(2)
delay(100)
emit(3)
}
flow.collect { value ->
println("Collected $value")
delay(200) // 模拟处理每个数据项需要时间
println("Collected $value, done")
}
}
输出:
bash
Collected 1
Collected 1, done
Collected 2
Collected 2, done
Collected 3
Collected 3, done
collectLatest
collectLatest
也是一个挂起函数,用于收集 Flow
中发射的数据。但是,当有新的数据项发射时,如果上一个数据项的处理尚未完成,collectLatest
会取消上一个数据项的处理,并开始处理新的数据项。
示例:
Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking<Unit> {
val flow = flow {
emit(1)
delay(100)
emit(2)
delay(100)
emit(3)
}
flow.collectLatest { value ->
println("Collected $value")
delay(200) // 模拟处理每个数据项需要时间
println("Collected $value done")
}
}
输出:
bash
Collected 1
Collected 2
Collected 3
Collected 3 done
在上述示例中,当 2
被发射时,1
的处理被取消,转而处理 2
。同样,当 3
被发射时,2
的处理被取消,转而处理 3
。因此,虽然 delay(200)
模拟了较长的处理时间,但每个数据项之间的延迟被忽略,因为新的数据项不断涌入,导致未完成的处理被取消。
选择使用
- 使用
collect
时,每个数据项都会被完整处理,不会被取消。这适用于需要确保所有数据项都被处理的场景。 - 使用
collectLatest
时,如果新的数据项在处理当前数据项时到达,当前数据项的处理会被取消。这适用于希望响应最新数据,而不关心旧数据是否被完整处理的场景。
总结
collect
适用于需要按顺序处理所有数据项的场景。collectLatest
适用于只关心最新数据,可能会丢弃尚未处理完的数据项的场景。
---- 文章由 ChatGPT 生成