여러 Flow 하나로 합치기

복수의 Flow를 합치는 다양한 방법이 있다.

zip

fun <T1, T2, R> Flow<T1>.zip(
    other: Flow<T2>, 
    transform: suspend (T1, T2) -> R
): Flow<R>
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking<Unit> {
    val nums = (1..3).asFlow()
    val str = flowOf("one", "two", "three")
    nums.zip(str) { a, b ->
        "$a -> $b"
    }.collect {
        println(it)
    }
}

실행결과
1 -> one
2 -> two
3 -> three
zip은 두 플로우증 하나의 플로우가 끝나면, 플로우가 취소됨.

combine

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking<Unit> {
    val nums = (1..3).asFlow().onEach { delay(300) }
    val strs = flowOf("one", "two","three").onEach { delay(400) }
    val startTime = System.currentTimeMillis()

    nums.zip(strs) { a, b ->
        "$a -> $b"
    }.collect {
        println("$it at ${System.currentTimeMillis() - startTime} ms from start")
    }
}

실행결과
1 -> one at 422 ms from start
2 -> two at 828 ms from start
3 -> three at 1235 ms from start
fun <T> Flow<T>.onEach(action: suspend (T) -> Unit): Flow<T>
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking<Unit> {
    val nums = (1..3).asFlow().onEach { delay(300) }
    val strs = flowOf("one", "two","three").onEach { delay(400) }
    val startTime = System.currentTimeMillis()

    nums.combine(strs) { a, b ->
        "$a -> $b"
    }.collect {
        println("$it at ${System.currentTimeMillis() - startTime} ms from start")
    }
}

실행결과
1 -> one at 428 ms from start
2 -> one at 634 ms from start
2 -> two at 833 ms from start
3 -> two at 940 ms from start
3 -> three at 1239 ms from start
Flow의 결합을 추적하는 경우엔 combine, 최종 결과만 필요한 경우는 zip을 사용해야 하는 것 같음.
<https://velog.io/@sana/KotlinFlow-Flow-%EA%B2%B0%ED%95%A9-%EC%97%B0%EC%82%B0%EC%9E%90-zip-combine>

Flow를 Flatten하기