코딩하는 개굴이

[RxJava] Subject 란? 본문

안드로이드/RxJava

[RxJava] Subject 란?

개굴이모자 2023. 3. 5. 21:46
반응형

Subject 는 데이터 스트림과 subscriber 성격을 둘다 갖고있다.

Observable 과 Observer 를 둘다 구현한 추상 타입이기 때문에, 하나의 소스로부터 다수의 subscriber 에게 멀티 캐스팅이 가능한 장점이 있다.

Observer 를 직접 구현하기 때문에, onNext, onError, onComplete 등의 이벤트를 수동으로 subscriber 에게 전달해줄 수 있다.

 

데이터 스트림의 성격

예를들어 PublishSubject 를 기준으로 살펴보자.

간단하게 PublishSubject 는 가장 단순한 구현체로, 이벤트를 subscriber 에게 전달할 수 있다.

단, 구독한 시점에서부터 발생하는 데이터를 전달하기 때문에, 데이터가 모두 발행된 뒤 구독하면 받을 수 없다.

val subject = PublishSubject.create<Int>()  //여러 구독자를 붙여보자. subject.subscribe { 	println("subscriber A: $it") } subject.subscribe { 	println("subscriber B: $it") }  subject.onNext(1) subject.onNext(2)  //발행된 뒤에는 받을 수 없다. subject.subscribe { 	println("subscriber C: $it") }  //result subscriber A: 1 subscriber B: 1 subscriber A: 2 subscriber B: 2

 

 

Subscriber 의 성격

다른 데이터 스트림의 subscriber의 역할로서, 전달받은 데이터를 발생하는 동작의 구현 또한 가능하다. 다른 Observable 로부터 전달받은 데이터를 자신의 subscriber 에게 전달해주는 것이다. 아래와 같이 말이다.

Observable → Subject → Subscriber

 

ℹ️
하위 예시에서 사용된 interval 연산자는 주어진 시간 간격으로 순서대로 정수를 발행하는 Observable 이다. 주로, 자동으로 반복해서 특정 동작을 수행할 때 사용되며, 구독을 중지하기 전까지 아이템을 무한히 발행하기 때문에 불필요해지면 dispose 해주어야한다.
val observable1 = Observable.interval(1, TimeUnit.SECONDS) val observable2 = Observable.interval(500, TimeUnit.MILLISECONDS) val subject = PublishSubject.create<String>()  //observable 을 subject 가 구독한다. observable1.map { "This is A, print this please. value is $it" }.subscribe(subject) observable2.map { "This is B, print this please. value is $it" }.subscribe(subject)  //subject의 구독자를 등록한다. 구독자는 stirng 을 print 하는 동작을 수행한다. subject.subscribe(System.out::println)  //result This is B, print this please. value is 0 This is B, print this please. value is 1 This is A, print this please. value is 0 This is B, print this please. value is 2 This is B, print this please. value is 3 This is A, print this please. value is 1 ...

 

subject 는 두 observable 로부터 데이터를 전달받아서 처리하므로, Observable 의 merge/zip 연산자 등과 비슷한 동작을 수행하는 것을 볼 수 있다.

 

 

주의 사항

Subject 는 위처럼 두가지 성격을 동시에 가지고 있기 때문에 다재다능하고 편리해보인다. 실제로 그게 맞지만, 잘못 사용할 경우 Observable 규약을 깨뜨리거나, 구독을 하기 전에 불필요하게 수행이 불리는 등의 문제가 발생할 수 있다.

 

따라서, 사용에 앞서서 아래 두가지를 고려해볼 것을 권장한다.

  1. Subject 를 사용하기 전, Single.create(), fromCallable(), defer() 를 사용해 데이터 스트림을 만들 수 있는지 우선 고려한다.
  1. 다른 데이터 스트림을 구독하고 그 결과를 Subject 로 넘기는 패턴을 피한다.

 

참고 링크


Uploaded by

N2T
반응형

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

[RxJava] RxJava 빠르게 훑어보기  (1) 2023.06.18
[RxJava] Scheduler란?  (0) 2023.03.05
Comments