Kotlin Flows - collect vs collectLatest

Kotlin Flows - collect vs collectLatest

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.

How to choose between them?

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