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
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 규약을 깨뜨리거나, 구독을 하기 전에 불필요하게 수행이 불리는 등의 문제가 발생할 수 있다.
따라서, 사용에 앞서서 아래 두가지를 고려해볼 것을 권장한다.
- Subject 를 사용하기 전, Single.create(), fromCallable(), defer() 를 사용해 데이터 스트림을 만들 수 있는지 우선 고려한다.
- 다른 데이터 스트림을 구독하고 그 결과를 Subject 로 넘기는 패턴을 피한다.
참고 링크
Uploaded by
N2T