[RxJava] Observable 변형하기

H43RO·2021년 9월 5일
2

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개의 댓글