在 Kotlin 協程庫中,collect
和 collectLatest
都是用于收集 Flow
中發射的數據的方法,但它們在處理數據和響應新數據的方式上有所不同。
collect
collect
是一個掛起函數,用于收集 Flow
中發射的所有數據。它會按順序處理每一個發射的數據項,直到數據流結束。處理每一個數據項是一個同步操作,只有在處理完當前數據項后,才會開始處理下一個數據項。
示例:
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")}
}
輸出:
Collected 1
Collected 1, done
Collected 2
Collected 2, done
Collected 3
Collected 3, done
collectLatest
collectLatest
也是一個掛起函數,用于收集 Flow
中發射的數據。但是,當有新的數據項發射時,如果上一個數據項的處理尚未完成,collectLatest
會取消上一個數據項的處理,并開始處理新的數據項。
示例:
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")}
}
輸出:
Collected 1
Collected 2
Collected 3
Collected 3 done
在上述示例中,當 2
被發射時,1
的處理被取消,轉而處理 2
。同樣,當 3
被發射時,2
的處理被取消,轉而處理 3
。因此,雖然 delay(200)
模擬了較長的處理時間,但每個數據項之間的延遲被忽略,因為新的數據項不斷涌入,導致未完成的處理被取消。
選擇使用
- 使用
collect
時,每個數據項都會被完整處理,不會被取消。這適用于需要確保所有數據項都被處理的場景。 - 使用
collectLatest
時,如果新的數據項在處理當前數據項時到達,當前數據項的處理會被取消。這適用于希望響應最新數據,而不關心舊數據是否被完整處理的場景。
總結
collect
適用于需要按順序處理所有數據項的場景。collectLatest
適用于只關心最新數據,可能會丟棄尚未處理完的數據項的場景。
---- 文章由 ChatGPT 生成