관리 메뉴

나만을 위한 블로그

[Rxjava] Subject, BehaviorSubject란? 본문

개인 공부/Rxjava

[Rxjava] Subject, BehaviorSubject란?

참깨빵위에참깨빵_ 2021. 5. 8. 21:41
728x90
반응형

안드로이드에서 반응형 프로그래밍을 하기 위한 방법으로 Rxjava가 있다고 이전에 포스팅한 적이 있다.

onlyfor-me-blog.tistory.com/286

 

[Android] Rxjava란?

안드로이드 디벨로퍼 홈페이지나 예제를 찾다보면 rxjava라는 키워드를 한번쯤은 보게 된다. rxjava는 뭘까? 그리고 왜 쓰는 걸까? 먼저 rxjava가 뭔지부터 찾아봤다. github.com/ReactiveX/RxJava ReactiveX/RxJa.

onlyfor-me-blog.tistory.com

나중에 반응형 프로그래밍을 하게 될 일이 생길 수도 있기 때문에 따로 Rxjava 카테고리를 만들어서 따로 기록하려고 한다.

구구단 예제를 찾아서 빌드해보고 코드를 분석해봤는데 전혀 이해가 안 됐기 때문이 가장 크다.

먼저 Subject부터 기록한다.

 

reactivex.io/documentation/ko/subject.html

 

ReactiveX - Subject

만약, Subject를 정의했는데, 이를 Subscriber 인터페이스 없이 다른 에이전트에 전달하고 싶다면 그 Subject를 순수 Observable로 리턴하는 asObservable 메서드를 사용하면 된다. 참고

reactivex.io

Subject란 Observer나 Observable처럼 행동하는 ReactiveX의 일부 구현체에서 사용 가능한 일종의 교각 혹은 프록시다. 왜냐면 Subject는 Observer기 때문에 하나 이상의 Observable을 구독할 수 있고, 동시에 Observable이기도 해서 항목들을 하나하나 거치면서 재배출하고 관찰하며, 새로운 항목들을 동시에 emit(방출)할 수도 있다
하나의 Subject는 하나의 Observable을 구독하면서, (Observable이 "Cold" Observable인 경우 즉, 옵저버가 구독을 시작하기 전까지 항목들의 배출을 지연시키는 Observable일 경우) Observable이 항목들을 배출시키도록 동작시킨다. 그 결과로 인해 원래는 "Cold" Observable이었던 주제를 "Hot" Observable로 만들기도 한다.

cold와 hot의 차이는 아래와 같다.

youngest-programming.tistory.com/390

 

[RxJava] Subject 클래스 간략 정리 (feat. Hot, Cold Observable차이)

[2021-04-16 업데이트]  안녕하세요ㅎㅎ RxJava 책을 복습과 함께 틈틈히 정리하면 더 기억에 남을 것 같아 포스팅을 하게되었습니다. RxJava의 Observable 에는 Cold, Hot 두 종류의 Obsevable이 있습니다. 둘

youngest-programming.tistory.com

cold는 구독하기 전까지 데이터를 방출하지 않는 Lazy한 접근법이고 hot은 구독자의 존재 여부에 상관없이 데이터를 발행하는 Observable이다
cold를 사용하는 예시는 웹 요청, DB 쿼리, 파일 읽기 등이고 hot을 사용하는 예시는 마우스 / 키보드 / 시스템이벤트, 센서 데이터 등이 있다

 

 

www.tutorialspoint.com/rxjava/rxjava_subjects.htm

 

RxJava - Subjects - Tutorialspoint

RxJava - Subjects As per the Reactive, a Subject can act as both Observable as well as Observer. A Subject is a sort of bridge or proxy that is available in some implementations of ReactiveX that acts both as an observer and as an Observable. Because it is

www.tutorialspoint.com

Subject는 Observable, Observer로 모두 행동할 수 있다

Subject는 Observer, Observable이 모두 될 수 있는 요소인 듯하다.

이 Subject의 종류는 총 4가지 있는데 공식 홈페이지에선 아래와 같이 설명하고 있다.

AsyncSubject : 소스 Observable로부터 배출된 마지막 값(만)을 배출하고 소스 Observable의 동작이 완료된 후에야 동작한다. 만약 소스 Observable이 아무 값도 배출하지 않으면 AsyncSubject 역시 아무 값도 배출하지 않는다. 또한 AsyncSubject는 맨 마지막 값을 뒤이어 오는 Observer에 전달하는데, 만약 소스 Observable이 오류로 인해 종료될 경우, AsyncSubject는 아무 항목도 배출하지 않고 발생한 오류를 그대로 전달한다

BehaviorSubject : Observer가 BehaviorSubject를 구독하기 시작하면 옵저버는 소스 Observable이 가장 최근에 발행한 항목(또는 아직 아무 값도 발행되지 않았다면 맨 처음 값이나 기본 값)의 발행을 시작하며 그 이후 소스 Observable(들)에 의해 발행된 항목들을 계속 발행한다. 소스 Observable이 오류 때문에 종료되면 BehaviorSubject는 아무런 항목도 배출하지 않고 소스 Observable에서 발생한 오류를 그대로 전달한다

PublishSubject : 구독 이후에 소스 Observable(들)이 배출한 항목들만 옵저버에게 배출한다. 주의할 점은 PublishSubject는 (이를 막지 않는 이상) 생성 시점에서 즉시 항목들을 배출하기 시작할 것이고 이런 특성 때문에 주제가 생성되는 시점과 옵저버가 이 주제를 구독하기 시작하는 그 사이에 배출되는 항목들을 잃어버릴 수 있다는 단점이 있다. 따라서, 소스 Observable이 배출하는 모든 항목들의 배출을 보장해야 한다면 Create를 사용해서 명시적으로 "차가운" Observable(항목들을 배출하기 전에 모든 옵저버가 구독을 시작했는지 체크한다)을 생성하거나, PublishSubject 대신 ReplaySubject를 사용해야 한다. 소스 Observable이 오류 때문에 종료되면 BehaviorSubject는 아무런 항목도 배출하지 않고 소스 Observable에서 발생한 오류를 그대로 전달한다.

ReplaySubject : 옵저버가 구독을 시작한 시점과 관계 없이 소스 Observable(들)이 배출한 모든 항목들을 모든 옵저버에게 배출한다.
ReplaySubject는 몇 개의 생성자 오버로드를 제공하는데, 이를 통해 재생 버퍼의 크기가 특정 이상으로 증가할 경우 또는 처음 배출 이후 지정한 시간이 경과할 경우 오래된 항목들을 제거한다.
만약, ReplaySubject을 옵저버로 사용할 경우, 멀티 스레드 환경에서는 Observable 계약 위반과 주제에서 어느 항목 또는 알림을 먼저 재생해야 하는지 알 수 없는 모호함이 동시에 발생할 수 있기 때문에 (비순차적) 호출을 유발시키는 onNext(또는 그 외 on) 메서드를 사용하지 않도록 주의해야 한다.

www.tutorialspoint.com/rxjava/rxjava_subjects.htm

 

RxJava - Subjects - Tutorialspoint

RxJava - Subjects As per the Reactive, a Subject can act as both Observable as well as Observer. A Subject is a sort of bridge or proxy that is available in some implementations of ReactiveX that acts both as an observer and as an Observable. Because it is

www.tutorialspoint.com

Subject 이름 설명
PublishSubject 구독 후 방출되는 항목만 배출한다
ReplaySubejct Observable을 구독한 시기에 상관없이 소스 Observable에서
방출한 모든 항목을 방출한다
BehaviorSubject 구독 시 가장 최근 항목을 내보낸 다음 소스 Observable에서
방출한 항목을 계속 방출한다
AsyncSubject 방출이 완료된 후 소스 Observable이 방출한 마지막 항목을
방출한다

 

이 4가지 Subject 중 내가 예제에서 사용한 Subject는 Behavior Subject기 때문에 이를 먼저 확인한다.

 

www.tutorialspoint.com/rxjava/rxjava_behaviorsubject.htm

 

RxJava - BehaviorSubject - Tutorialspoint

RxJava - BehaviorSubject BehaviorSubject emits the most recent item it has observed and then all subsequent observed items to each subscribed Observer. Class Declaration Following is the declaration for io.reactivex.subjects.BehaviorSubject class − publi

www.tutorialspoint.com

BehaviorSubject는 가장 최근에 관찰한 항목을 방출한 다음 모든 후속 관찰 항목을 구독한 각 관찰자에게 방출한다

stackoverflow.com/questions/39494058/behaviorsubject-vs-observable

 

BehaviorSubject vs Observable?

I'm looking into Angular RxJs patterns and I don't understand the difference between a BehaviorSubject and an Observable. From my understanding, a BehaviorSubject is a value that can change over t...

stackoverflow.com

BehaviorSubject의 고유 기능은 아래와 같다.

1. next()를 받지 않은 경우에도 구독 시 항상 값을 반환해야 하므로 초기값이 필요하다
2. 구독 시 주제의 마지막 값을 반환한다. 일반 Observable은 onNext()를 수신할 때만 트리거된다
3. 언제든 getValue()를 써서 관찰할 수 없는 코드에서 주제의 마지막 값을 검색할 수 있다
또한 BehaviorSubject의 asObservable()을 통해 BehaviorSubject에서 Observable을 가져올 수 있다.  Observale은 제네릭이고 BehaviorSubject는 특정 품질(specific qualities)을 가진 Observable의 하위 유형이기 때문에, 기술적으로 BehaviorSubject는 Observable의 하위 유형이다

스택오버플로우의 답변대로 BehaviorSubject는 처음에 초기값을 설정해줄 수 있다.

방법은 create() 또는 createDefault()를 사용하는 것인데, 두 메서드의 차이는 공식 문서를 확인한 결과 아래와 같다

 

reactivex.io/RxJava/javadoc/io/reactivex/subjects/BehaviorSubject.html#create--

 

BehaviorSubject (RxJava Javadoc 2.2.21)

Subject that emits the most recent item it has observed and all subsequent observed items to each subscribed Observer. This subject does not have a public constructor by design; a new empty instance of this BehaviorSubject can be created via the create() m

reactivex.io

create() : 기본 항목 없이 BehaviorSubject를 만든다
createDefault(T defaultValue) : 관찰한 마지막 항목과 구독하는 각 Observer에 모든 후속 항목을 방출하는 BehaviorSubject를 만든다

- defaultValue : BehaviorSubject가 소스 Observable에서 항목을 아직 관찰하지 않은 한, 모든 Observer에게 먼저 방출될 항목

 

반응형
Comments