Programming/Android

RxJava 적용기

YK Choi 2021. 10. 3. 15:48

RxJava는 러닝커브가 다소 있는 것으로 알려져 있다.

 

coroutine+suspend fun 와 비교해서 높은 수준의 작업을 실시간으로 처리할 수 있고,

coroutine Flow 와 비교해서 더 안정적인 프로그래밍을 할 수 있다는 장점으로 인해 배울 가치는 충분한 것 같다.

 

배워야할 개념도 많고 빠른 기간 내에 전부 이해할 것은 기대하지 않지만

LiveData에서의 observe, Flow에서의 일부 오퍼레이터 경험(맛보기) 이 있으니 어느정도는 유리하게 시작할 수 있지 않을까?ㅎㅎ

 

차근차근 시작해보자

 

중요한 개념 Observable / Observer

RxJava에서는 Observable을 구독하는 Observer가 존재하고, Observable이 순차적으로 발행하는 데이터에 대해서 반응한다. 

 

observer는 onNext, onError, onCompleted 라는 3가지 함수들을 가지고 있다. 이 3가지 함수를 observer의 함수라고 부른다.(observer’s method)

 

- onNext() : Observable은 자신이 정상적으로 item을 방출할 때마다 observer의 onNext 함수를 호출한다. 이 onNext 함수는 인자로 Observable로 부터 방출된 item을 갖게 된다.

- onError() : Observable이 item을 방출하는 것을 실패했거나 어떠한 다른 에러가 발생했을 때는 onError 함수를 호출한다. 이 onError 함수가 호출되고 나서는 더 이상 onNext 함수나 onCompleted 함수가 호출되지 않을 것이다. onError 함수는 인자로 에러의 원인을 나타내는 것을 갖게 된다.

- onCompleted() : Observable이 어떠한 오류도 만나지 않은 상태에서 onNext 함수 호출을 마지막으로 한 후에는 반드시 이 onCompleted 함수를 호출한다. 즉, Observable이 방출할 item이 더 이상 존재하지 않아 onNext 함수를 방출할 일이 없어졌을 때 onCompleted 함수를 방출하는 것이다.

 

* onNext() 를 emit의 방출이라도 부르고, onError()와 onCompleted()를 notification의 호출이라고 한다.

 

 

Hot Observable vs Cold Observable

Hot Observable : 라이브 방송을 시청하는 것처럼, 아이템 발행이 시작된 이후로 모든 구독자에게 동시에 같은 아이템을 발행한다.

Cold Observable : Youtube 동영상을 재생하는 것처럼, 구독을 요청하면 아이템을 발행하기 시작한다.

 

비유가 진짜 너무 찰떡인것 같다.

 

 

Single Class

Single 클래스는 observable 클래스의 특수한 케이스이다.

Observable는 item을 연속으로 무한히 발행할 수 있지만 Single 클래스는 단 하나의 item만 발행하거나 하나의 에러 notification만 발행한다는 점이 Single 클래스만의 특징이다.

 

이런 Single 클래스의 특징 때문에 Single 클래스로 Observable을 생성하면 Observable로 부터 onNext, onError, onCompleted 함수가 호출되는 것이 아니라 onSuccess  onError 함수만 호출된다.

- onSucess() : Single 클래스로 생성된 Observable은 단 한 개의 아이템을 방출하고 이 때 Single은 onSuccess 함수를 호출한다. 따라서 방출된 단 한 개의 item만이 이 onSuccess 함수와 함께 사용된다.

- onError() : onError 함수가 호출되면 Single 클래스로 생성된 Observable이 item을 방출할 수 없게 된 원인을 알 수 있다.

 

Single Observable은 위 두 함수 중 단 하나의 함수만을 딱 한 번 호출하게 된다.

item 방출에 성공할 경우에는 onSuccess 함수 하나만을 호출하고, item 방출에 실패할 경우에는 onError 함수 하나만을 호출하기 때문이다.

그리고 두 함수 중 하나를 호출한 후에는 Single이 종료되고 observer와의 연결도 끊어지게 된다.

 

Subject Class

Subject는 Observable 처럼 행동할 수 있고, observer 처럼 행동할 수도 있다.

Subject는 AsyncSubject, BehaviorSubject, PublishSubject, ReplaySubject로 나뉠 수 있다. 이것에 대해서는 조금 나중에 다시 알아봐야겠다.

 

ReactiveX의 연산자들

ReactiveX의 대부분의 연산자들은 Observable을 입력값으로 가지고 작동시킨 후, 다시 Observable을 return 하도록 되어 있는 경우가 많다. Rx 연산자의 이러한 특징을 사용해서 연산자를 Chain의 형태로 작성할 수 있다.

즉, 바로 이전의 연산자에서 반환되는 Observable로 다음 연산자의 입력값으로 들어갈 수 있다는 것이다.

 

ReactiveX의 카테고리 별 연산자는 아래와 같다. 괄호 안에는 연산자를 예시로 몇개 적었다.
1. observable 생성 (Create, Just)

2. observable 변환 (FlatMap, Map, Buffer)
3. observable 필터링 (Filter)
4. observables 결합 (And, Then, When, Join)
5. 오류 처리 연산자 (Catch, Retry)
6. observable 유틸리티 연산자 (Do, observeOn, subscribe, subscribeOn, Serialize)
7. 조건과 Boolean 연산자 (All, Contains)
8. 수학과 집계 연산자 (Count, Sum, Max, Min)
9. BackPressure 연산자 (observable을 복제하는 전략이라고 한다)
10. 연결 가능한 observable 연산자 (Publish, Connect, Replay)
11. observable 변환 연산자 (To)

 

 

이중에서 자주 사용되는 연산자에 대해 알아보자

1. map()

2. flatMat()

3. filter()

4. reduce()

 

- map()은 Observable로부터 방출된 item을 어떠한 함수에 적용시켜서 다시 방출해주는 함수이다.

- flatMap() map과 조금 비슷하지만 차이가 있다. map()은 입력값을 어떤 함수에 넣어서 변환시켜주는 일대일 함수지만 flatMap()함수는 입력값을 함수에 넣으면 결과가 Observable로 나온다.
즉, flatMap()의 결과로 나온 Observable은 그 스스로도 item을 방출할 수 있다. 또한 flatMap()은 일대일 또는 일대다 observable함수이다.

- filter()는 Observable이 모든 item을 방출하는 것이 아니라 어떤 조건에 맞는 item만을 방출하도록 하게 해준다.

- reduce()는 observable이 방출하는 각각의 item에 어떠한 함수를 적용시킨 후 마지막 결과값을 반환해준다.

 

 

살짝 발을 담궈보니 확실히 배울 것들이 많다는 것을 알 수 있었다.

프로젝트를 하면서 코드영역에서도 학습해봐야 할것 같다.