Coroutines/Flow

[Coroutine Flow] flatMapLatest 이용해 최신 데이터만 사용해 flow 변환하기

반응형

flatMapLatest란?

flatMapLatest는 flow를 최신데이터만을 이용해 새로운 flow로 변환할 수 있도록 도와주는 함수이다. flatMapLatest를 사용하면 flow에서 발행된 데이터를 변환하는 도중 새로운 데이터가 발행될 경우, 변환 로직을 취소하고 새로운 데이터를 사용해 변환을 수행한다.

 

collectLatest의 경우 먼저 발행된 데이터를 처리하는 도중 새로운 데이터가 들어올 경우 이전 데이터 처리를 취소하고 새로운 데이터를 이용해 데이터를 처리하는데 flatMapLatest는 collectLatest와 동작이 매우 유사하다. 

 

flatMapLatest  동작 살펴보기

예를 들어 다음과 같은 flow가 있다고 해보자. 이 flow는 1과 5를 순차적으로 발행한다.

val flow = flow<Int> {
    emit(1)
    emit(5)
}

 

위 flow에서 발행되는 데이터 값을 기존 값에 +1,+2,+3을 수행하는 새로운 flow 로 변환하려고 한다. 즉 1의 경우 2, 3, 4를 발행하는 새로운 flow로 변환되며 5는 6, 7, 8에 해당하는 flow로 변환된다. 이러한 flatMapLatest를 이용해 수행하기 위해서는 다음과 같이 코드를 만들면 된다.

fun collectWithFlatMapConcat() {
    viewModelScope.launch {
        flow.flatMapLatest { intValue ->
            flow {
                emit(intValue + 1)
                emit(intValue + 2)
                emit(intValue + 3)
            }
        }.collect {
            println("printed value >> $it")
        }
    }
}

 

위 코드를 수행하면 다음과 같이 결과값이 나온다.

그림1.  flatmapLatest 예시

 

그렇다면 변환에 처리가 오래 걸리게 만들면 어떻게 될까? 예를 들어 아래와 같이 +1 변환과 +2 변환 사이에 1초의 delay를 줘보도록 하자.

fun collectWithFlatMapConcat() {
    viewModelScope.launch {
        flow.flatMapLatest { intValue ->
            flow {
                emit(intValue + 1)
                delay(1000)
                emit(intValue + 2)
                emit(intValue + 3)
            }
        }.collect {
            println("printed value >> $it")
        }
    }
}

flatMapLatest는 이전 데이터가 변환되기 전에 새로운 데이터가 들어오면 이전 데이터에 대한 변환이 취소되므로, 위와 같이 변환 로직에 delay를 주면 첫번째 데이터(1)에 대한 +1은 처리될 테지만 +2가 처리되기 전에 두번째 데이터(5)가 발행된다.

 

즉 첫 데이터(1)에서는 2만 생성되고 3, 4가 생성되기 전 변환 로직이 취소된다. 따라서 다음과 같은 결과가 나오게 된다.

 

 

반응형

 

이 글의 저작권은 Kotlin World 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.