본문 바로가기
Android 개발/Coroutine , Flow, Channel

onEach vs onStart 비교 정리 # Kotlin Coroutine Flow

by Developer88 2023. 5. 3.
반응형

오늘은 Kotlin Coroutine Flow의 onEach 와 onStart 에대해서 정리해 보도록 하겠습니다.

 

1. onEach

flow 에서 아이템이 흘러나올 때 마다,

실행하도록 해야하는 코드가 있다면, 이 연산자를 사용하는 것이 좋습니다.

upstream 즉 위의 flow 에서 흘러나오는 값을 그대로 전달해 주기 때문에,

흘러나가는 데이터에는 영향을 주지 않습니다.

 

 

코드를 보면서 이해해 보도록 하겠습니다.

 

val flow = flowOf(1, 2, 3, 4, 5)

flow
    .onEach { item ->
        println("Item emitted: $item")
    }
    .map { item ->
        item * 2
    }
    .collect { result ->
        println("결과: $result")
    }

 

 

위 코드의 결과는 다음과 같습니다.

 

Item emitted: 1
결과: 2
Item emitted: 2
결과: 4
Item emitted: 3
결과: 6
Item emitted: 4
결과: 8
Item emitted: 5
결과: 10

 

 

2. onStart

위의 onEach 가 flow 아이템들이 흘러나올 때 마다 어떤 코드를 실행시키기 위한 것이었다면,

onStart 는 flow 아이템들이 흘러나오기 전에,

실행되어야 하는 코드들을 위해서 사용되는 연산자입니다.

 

 

코드를 보도록 하겠습니다.

 

fun main() = runBlocking<Unit> {
	val numbers = flowOf(1, 2, 3, 4, 5)
    .onStart { 
        println("Flow 시작")
    }
    .map { it * 2 }
	numbers.collect { println("결과: $it") }
}

 

 

결과는 다음과 같습니다.

아이템이 흘러나오기 전 최초 한번만 시작 되는 것을 볼 수 있습니다.

그리고 아이템으로 흘러나온 것이 아니라,

개별적으로 onStart 블록만 실행된 것도 볼 수 있습니다.

즉, 흘러나오는 아이템에 영향을 주지 않은 것 입니다.

 

Flow 시작
결과: 2
결과: 4
결과: 6
결과: 8
결과: 10

 

3. 비교

둘을 비교하기 위해서, 다음의 코드를 실행해 보겠습니다.

아주 단순한 Integer 5개를 흘려보내는 코드를 실행해 보도록 하겠습니다.

 

fun main() = runBlocking {
    val numberFlow = flowOf(1, 2, 3, 4, 5)

    val processedFlow = numberFlow
        .onStart {
            println("Flow is about to start")
        }
        .onEach { number ->
            println("Processing number: $number")
        }
    processedFlow.collect()
}

 

 

결과는 다음과 같은데요.

onStart의 코드는 한번만 실행되었구요.

onEach의 코드는 아이템이 흘러나올때마다 실행된 것을 볼 수 있습니다.

 

Flow is about to start
Processing number: 1
Processing number: 2
Processing number: 3
Processing number: 4
Processing number: 5

 

728x90

댓글