Flow 수집하기

TRASALBY·2024년 3월 19일
0

학습내용 옮기기

목록 보기
7/8

collect와 collectLatest의 차이

collect를 사용한 데이터 소비의 한계

Flow는 Coroutine에서 Reactive한 프로그래밍을 할 수 있도록 만들어진 데이터 파이프라인이다.

public suspend inline fun <T> Flow<T>.collect(crossinline action: suspend (value: T) -> Unit): Unit =
    collect(object : FlowCollector<T> {
        override suspend fun emit(value: T) = action(value)
    })
  • collect의 인자로 들어가는 action 블록은 flow에서 발행된 데이터를 순차적으로 받아 suspend fun을 수행한다.
  • 하지만 이 collect를 잘못 사용하면 새로운 데이터가 발행되더라도 데이터 처리가 제대로 되지 않을 수 있다.

만약 데이터 2의 시간이 오래 걸릴 경우? → 데이터3의 표기 또한 지연 된다.

중간에 있는 데이터가 처리되는데 시간이 무제한으로 걸린다면 이후 발행되는 데이터는 모두 처리가 되지 않을 것이다.

이 문제는 최신 데이터가 들어왔을때 이전 데이터를 이요해 수행하던 suspend fun을 취소하고 새로 들어온 suspend fun을 수행하도록 하여 해결 할 수 있다.

이것이 collectLastest의 동작이다.

collect

새로운 데이터가 들어왔을 때 이전 데이터의 처리가 끝난 후에 새로운 데이터를 처리한다.

collect는 데이터를 소비하면서 데이터의 발행 속도가 소비속도보다 빠를 경우 소비가 지연된다.

예를 들어 숫자 0에서 10까지 1초만에 모든 발행이 마무리 되었지만 소비는 1초에 하나씩 하게 될 경우 총 10초에 걸쳐 출력된 것을 확인 할 수 있다.

collectLatest

새로운 데이터가 들어오면 이전의 데이터 처리는 종료하고 새로운 데이터를 처리한다.

collectLatest는 항상 최신의 데이터를 소비하기 때문에 소비에 시간이 걸리더라도 발행에 걸린 1초만에 모든 작업이 완료 된 것을 볼 수 있다.

항상 최신 데이터를 표시해야 하는 UI 작업에 대해서는 collectLatest가 더 적합하다고 생각 할 수 있을 것이다.

collectLatest의 한계

사실 데이터의 delay는 소비되기 전에 일어나는 것이 보통이다.

위의 그림과 같이 데이터 발행 시간 사이의 간격 보다 데이터를 처리하는 suspend fun이 수행하는 시간이 오래 걸릴 경우 새로 들어온 데이터가 계속 취소되게 된다.

이런 상황에서 collectLatest는 아무 중간 데이터를 얻지 못하고 마지막 데이터만을 얻게 된다.

buffer를 이용해 발행과 소비 Coroutine 분리

collect에서 발행과 소비가 이뤄지는 방식

collect는 하나의 Coroutine에서 발행과 소비가 같이 일어난다.

  • 데이터가 발행 된 후 소비가 끝나고 다시 다음 데이터가 발행된다.
  • 발행, 소비 되는 쪽의 delay를 미리 처리하지 않는다면 양 쪽 모두에서 delay가 발생한다.

발행에 1초, 소비에 3초 걸리는 코드의 경우 총 4초의 지연이 발생하게 된다.

따라서 발행과 소비가 한 Coroutine에서 순차적으로 일어나는 것은 매우 비효율적이다.

buffer를 이용한 최적화

발행과 소비를 각각의 Coroutine으로 분리

buffer는 발행, 소비하는 코루틴을 분리하는 역할을 한다. 별도의 코루틴에서 발행과 소비가 이루어 지기 때문에 각각의 지연이 서로에게 영향을 미치지 않는다

0개의 댓글

관련 채용 정보