[RxJava] Observable 변형하기

H43RO·2021년 9월 5일

Reactive Programming

목록 보기
8/16
post-thumbnail

🔔 앞으로의 Reactive X 시리즈는 RxJava, RxKotlin 기준으로 작성됩니다
공식 문서를 참고하여 작성된 포스팅입니다.

이전 포스팅과 이어집니다.

Observable 변형해보기

Observable 을 변형한다 함은, 데이터를 특정 형태로 변형하여 발행하는 것이다. 어떤 비동기 기능을 개발할 때, 상황에 따라 알맞은 형태로 반환받고 싶어질 때가 있다. 이럴 때를 대비하여 이번 포스팅에서는, Observable 을 변형하는 다양한 연산자들에 대하여 알아보자.


buffer() 메소드

우리는 버퍼 라는 단어 자체를 많이 본 적이 있고, 대략 어떤 역할을 하는 녀석인지도 알고 있다. buffer() 메소드 역시 비슷한 동작을 하게 된다.

아래 코드를 통해 동작을 이해해보자.

fun main() {
    Observable.range(0, 8)
        .buffer(3)
        .subscribe {
            println("마! 이게 버퍼다!")
            it.forEach {
                println(it)
            }
        }
}
마! 이게 버퍼다!
0
1
2
마! 이게 버퍼다!
3
4
5
마! 이게 버퍼다!
6
7

buffer(3) 이하 함은, Observable 이 발행하는 데이터를 3개 씩 버퍼링하여 데이터를 발행해주는 역할을 한다. List 형태로 데이터들을 묶어준다. 출력 결과를 보면 이해될 것이다.


map() 메소드

얘는 Observable 이 발행하는 데이터 하나 하나를, 지정한 함수 동작로 매핑해서 값을 변환한다. 필자는 개인적으로 'Observable 변환' 이라하면 가장 먼저 떠오르는 녀석이 map() 인 것 같다.

아래 코드를 보면, 발행되는 데이터 각각에 10을 곱하고 이를 String 으로 변환하여 반환한다.

fun main() {
    val intStream = Observable.just(1, 2, 3)
    val stringStream = intStream.map {
        (it * 10).toString()
    }

    stringStream.subscribe {
        println("[${it.javaClass}] : $it")
    }
}
[class java.lang.String] : 10
[class java.lang.String] : 20
[class java.lang.String] : 30

flatMap() 메소드

이 녀석은 Observable 에서 발행된 데이터들 각각에 대해서, map 처럼 다른 값으로 변환하여 이를 또 다른 Observable 형태로 반환해주는 역할을 한다. 반환 형태가 결국 Observable 이기 때문에 새롭게 생성된 데이터들이 하나씩 순서대로 발행되는 Flatten 된 형태이다.

코드를 보며 이해해보자.

fun main() {
    val stream = Observable.just("A", "B", "C")
    
    stream.flatMap {
        Observable.just(
            "[$it] - 1",
            "[$it] - 2"
        )
    }.subscribe {
        println(it)
    }
}
[A] - 1
[A] - 2
[B] - 1
[B] - 2
[C] - 1
[C] - 2

발행되는 데이터 각각에 대해 새로운 Observable 를 생성하여, 지정된 특정 연산을 거쳐 Flatten 되어 Observable 형태로 발행되는 새로운 데이터들을 받아볼 수 있다.

flatMap() 은 Observable 작업을 여러 번 연계하여 사용할 때 유용하다.


scan() 메소드

scan() 은 발행된 데이터를 다음에 발행되는 데이터의 첫 번째 인자로 전달해주는 녀석이다.

위의 예시 마블 다이어그램대로 코드를 짜보자.

fun main() {
    Observable.just("A", "B", "C", "D", "E")
        .scan { x: String, y: String ->
            x + y
        }
        .subscribe {
            println(it)
        }
}
A
AB
ABC
ABCD
ABCDE

즉, 데이터를 발행하면 해당 데이터를 다음에 발행되는 데이터의 첫 번째 인자 ( x ) 로 전달한다.


이 외에도 groupBy, window 등의 녀석들이 있으니 꼭 공식문서를 통해 추가적으로 공부해보길 바란다.

profile
어려울수록 기본에 미치고 열광하라

0개의 댓글