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 변환과 +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 Coroutines 공식 기술 문서 번역이 GitHub 오픈소스로 배포되었습니다. Starganizer가 되어 오픈소스를 지지해주세요.