Kotlin Flows - collect vs collectLatest

Student @ National Institute of Technology, Delhi.
Android | Kotlin | Go | Python
Search for a command to run...

Student @ National Institute of Technology, Delhi.
Android | Kotlin | Go | Python
Haven't really used this yet myself. Bookmarked this for my future reference. Good one, thanks!
Failures are Inevitable Network calls might time out, APIs might be temporarily unavailable, or databases might become unreachable. To handle such transient errors gracefully, implementing a retry mechanism is crucial. This article will guide you thr...

In the last article, we covered data classes in Kotlin. We saw how they simplify class creation and make it faster with less coding. Now, let's explore Sealed Classes. Sealed Classes in Kotlin are a specialized form of abstract classes. They limit su...

Efficient Data Structuring in Android Development with Kotlin's Data Classes

Learn about Kotlin type hierarchy, type checks and type casts

Understanding and Utilizing Polymorphism and Inheritance in Kotlin for Effective Development

Kotlin Coroutines and Flows make asynchronous programming really easy to understand. And in this post, we'll look at two important but slightly different operators - collect and collectLatest
Both collect and collectLatest are terminal operators i.e. they will actually start the flow.
Now let's see how are they different?
First of all, let's build a flow
fun intFlow() = flow {
(1..5).forEach {
delay(50)
println("Flowing $it...")
emit(it)
}
}
Please note that there is a delay of 50 ms in the builder.
collect { }suspend fun main() {
intFlow().collect {
delay(100)
println("\t\t\t\t$it received")
}
}
Note that there is a delay of 100 ms in the collector. Next, let's see the execution:
Flowing 1...
1 received
Flowing 2...
2 received
Flowing 3...
3 received
Flowing 4...
4 received
Flowing 5...
5 received
At first look, you might not see it but look closely. In this case, the builder suspends until the collector is ready for the next value. That is evident because collector delays for 100 ms while builder only delays for 50.
Now, let's see what happens with collectLatest
collectLatest { }suspend fun main() {
intFlow().collectLatest {
delay(100)
println("\t\t\t\t$it received")
}
}
Flowing 1...
Flowing 2...
Flowing 3...
Flowing 4...
Flowing 5...
5 received
In this case, the collector is canceled when it receives a new value from the builder and starts with that value. This is clear because, after 50 ms, the builder provides a new value to the collector.
The tradeoff between collect { ... } and collectLatest { ... } is fairly straightforward. If you need to process all the values you receive you should use collect, if you want only the "latest" value to be processed, use collectLatest.
This is all, if you found this article helpful, please drop a like. :)
Cover Photo by Deepak Rautela on Unsplash