ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RxJava - combineLatest
    개발/안드로이드 2020. 6. 28. 17:44

     

    combineLatest 함수는 모든 Observable 소스에서 이벤트를 받은 후 마지막으로 받은 소스의 시점에서 새로운 이벤트를 만들고 싶을 때 사용한다. 아래 그림을 보면 두개의 소스를 받고 있고 각각 마지막으로 추가된 작업에 대해서 마다 새로운 이벤트를 형성해주고 있다.

     

     

    위와 같은 구조는 모든 데이터를 받고 난 다음에 한번에 업데이트 하고 싶은 경우나 하나의 소스가 변경될 때마다 최종적으로 입력된 Observable 소스를 불러오고 싶은 경우 유용하다. 추상적으로 서술해서 감이 잘 오지 않는데 각 경우의 예를 생각해보면 이해하기 쉬울 것 같다. 

     

    첫번째의 예로는 서버에서 받은 정보를 앱의 화면에 노출할 때로 볼 수 있을 것 같다. 컨텐츠 페이지에서 페이지의 정보와 댓글 리스트를 화면에 뿌려줘야 하는데 이 리스트가 다른 api로 분기되어 있다면 각각을 분리해서 호출해야 하고 화면 업데이트도 한번에 이뤄지지 않아 따닥따닥 이뤄질 수 있다. 이렇게 분리된 경우는 로딩 아이콘 표시하는 작업도 각 호출별로 설정해줘야해서 번거로운데 이럴 때는 combineLatest 구조를 이용해서 모든 소스를 받고 난 다음에 업데이트 하도록 두 소스를 묶어줄 수 있다.

     

    코드로 표현하면 이렇다. Flowable의 combineLatest 함수로 묶어서 댓글과 컨텐츠 리스트를 Flowable 소스로 받고 모든 소스가 도달 했을 때 loading 이 종료되었음을 false로 알릴 수 있다.

     

    Flowable.combineLatest(
        getReplyList(),
        getContentList(),
        BiFunction<List<String>, List<String>, Pair<List<String>, List<String>>> {
            replyList, contentList ->
            Pair(replyList, contentList)
        }
    )
        .doOnNext { loading.onNext(false) }
        .doOnNext { pair -> 
            val replyList = pair.first
            val conentList = pair.second
        }
        .subscribe()
        
    private fun getReplyList(): Flowable<List<String>> = Flowable.fromCallable {
        listOf("Hello", "World", "RxJava", "Flowable")
    }
    
    private fun getContentList(): Flowable<List<String>> = Flowable.fromCallable {
        listOf("This", "is", "developer")
    }

     

    두번째 경우로는 웹사이트에서 로그아웃이 된 경우 새로고침시 파라미터로 넣을 정보가 Observable 소스로 된 경우다. 로컬 저장소에 유저의 id를 이용해 로그인 유무를 판단하고 유저 상태 변경시 홈 api를 호출해야 하는데 이때 Observable 소스로 된 로컬 토큰 정보가 필요하면 id 가 변경될 때마다 token 정보를 새롭게 받도록 combineLatest로 묶어줄 수 있다. 코드로 표현하면 아래와 같다. 

     

    Flowable.combineLatest(
        id().distinctUntilChanged(),
        token(),
        BiFunction<Long, String, Pair<Long, String>> { id, token ->
            Pair(id, token)
        }
    )
        .flatMap { pair -> 
            val id = pair.first
            val token = pair.second
        
            home(id, token)
        }
        .subscribe()

     

    combineLatest로 묶을 수 있는 소스의 개수는 최대 9개까지 가능하다. 그런데 이정도로 많은 소스를 combineLatest로 묶는 경우는 거의 희박할 뿐더러 관리하기도 어렵다. 가능하면 3, 4개 까지 사용하는게 코드 유지 관리 측면에서도 좋다.

     

    '개발 > 안드로이드' 카테고리의 다른 글

    RxJava - debounce  (0) 2020.07.04
    RxJava - observeOn, subscribeOn  (0) 2020.06.28
    status bar 영역 덮는 view 만들기  (0) 2020.06.24
    Lottie 라이브러리  (0) 2020.06.24
    MediaCodec - Encoding  (0) 2020.06.21

    댓글

Designed by Tistory.