Elye
Elye

Reputation: 60111

What's the difference between flow and channelFlow?

I have both codes below, and the result looks the same for me

val namesFlow = flow {
    println("Start flow")
    (0..10).forEach {
        // Emit items with 500 milliseconds delay
        delay(500)
        println("Emitting $it")
        emit(it)
    }
}.map { it * it }

fun main() = runBlocking {
    namesFlow.collect { println(it) }
    namesFlow.collect { println(it) }
    println("Finish Flow")
}

and

val namesFlow = channelFlow {
    println("Start flow")
    (0..10).forEach {
        // Emit items with 500 milliseconds delay
        delay(500)
        println("Emitting $it")
        send(it)
    }
}.map { it * it }

fun main() = runBlocking {
    namesFlow.collect { println(it) }
    namesFlow.collect { println(it) }
    println("Finish Flow")
}

What's the difference between flow and channelFlow?

Upvotes: 7

Views: 5188

Answers (1)

Marko Topolnik
Marko Topolnik

Reputation: 200168

The purpose of channelFlow is being able to retrieve the results from a concurrently running coroutine. Here's an example from its documentation that merges another flow into the current one by concurrently collecting both the current and the other flow, sending all the data to the same channel:

fun <T> Flow<T>.merge(other: Flow<T>): Flow<T> = channelFlow {
    launch {
        collect { send(it) }
    }
    other.collect { send(it) }
}

Since your code makes no use of the ability to call send from a concurrent coroutine (something you can't do with emit), both examples in your question have the same behavior.

Upvotes: 7

Related Questions