개발일기

Kotlin Flow 실전 활용법

뱅우 2025. 8. 13. 09:47
반응형

Kotlin Flow 실전 활용법

1. Flow란 무엇인가?

Flow는 코틀린에서 제공하는 비동기 데이터 스트림 처리 도구로, RxJava의 대안이자 경량화된 리액티브 프로그래밍을 구현할 수 있는 API입니다. 콜드 스트림(Cold Stream) 방식으로 동작해 구독(subscribe)이 이루어져야 데이터가 흐르기 시작합니다.


2. 기본 구조

fun getNumbers(): Flow<Int> = flow {
    for (i in 1..5) {
        emit(i) // 데이터 방출
        delay(100) // 비동기 처리 시뮬레이션
    }
}

fun main() = runBlocking {
    getNumbers().collect { value ->
        println("받은 값: $value")
    }
}
  • flow { } : 데이터를 방출(emit)하는 빌더
  • collect { } : Flow를 소비(consume)하는 최종 연산자

3. 자주 쓰는 연산자

연산자 설명 예제
map 데이터 변환 .map { it * 2 }
filter 조건 필터링 .filter { it % 2 == 0 }
onEach 각 데이터 처리 후 부수 작업 .onEach { println(it) }
take 일부 데이터만 수집 .take(3)
debounce 짧은 시간 내 중복 이벤트 제거 .debounce(300)
getNumbers()
    .filter { it % 2 == 0 }
    .map { "짝수: $it" }
    .collect { println(it) }

4. 실무 예제: 검색창 자동완성

사용자가 입력할 때마다 API를 호출하는 것은 비효율적입니다. debouncedistinctUntilChanged를 사용하면 불필요한 호출을 줄일 수 있습니다.

val queryFlow = MutableStateFlow("")

fun observeSearch() {
    viewModelScope.launch {
        queryFlow
            .debounce(300) // 입력 멈춘 뒤 300ms 대기
            .distinctUntilChanged() // 같은 문자열 중복 제거
            .filter { it.isNotBlank() }
            .flatMapLatest { query ->
                searchApi(query) // suspend fun
            }
            .catch { e -> println("에러: $e") }
            .collect { result ->
                updateUi(result)
            }
    }
}
  • flatMapLatest : 마지막 입력에 대해서만 API 호출
  • debounce : 빠른 타이핑 중간에 불필요한 호출 방지
  • distinctUntilChanged : 같은 검색어 반복 호출 방지

5. Flow와 LiveData 연동

fun Flow<T>.asLiveData() = this.asLiveData()

val searchResultsLiveData = queryFlow
    .debounce(300)
    .flatMapLatest { searchApi(it) }
    .asLiveData()

UI 레이어에서는 LiveData를 그대로 observe할 수 있습니다.


6. 결론

  • Flow는 가볍고 선언적인 비동기 처리 방식
  • debounce, distinctUntilChanged, flatMapLatest는 실무에서 필수 패턴
  • RxJava 대비 배우기 쉽고 코루틴과 완벽 호환
  • 단, 콜드 스트림 특성 때문에 collect 시점과 스코프 관리가 중요
반응형