본문 바로가기
💻 프로그래밍

[RxJava] #2 Subject

by 콩드로이드 2022. 8. 2.

지난 포스팅에 이어서 RxJava의 Subject에 대해 알아보겠습니다

 

💡 Subject

• 구독자, 생성자의 특징을 둘 다 가짐 (여러개의 Observable을 구독할 수 있고,  데이터를 방출할 수 있다)

Cold Observable을 Hot Observable로 변경

🔥 Hot Observable

데이터 구독 여부와 관계 없이 데이터를 배출

❄️ Cold Observable

데이터를 구독을 시작해야 데이터가 배출 

 


 

Subject의 종류

 

📍 AsyncSubject

 

AsyncSubject

 

• 해당 Observable이 완료된 후 마지막 데이터만 발행합니다

 에러가 발생한다면 어떠한 데이터도 발행하지 않고, 에러만 발행합니다 

 

val subject: AsyncSubject<String> = AsyncSubject.create()
    subject.apply {
       onNext("first")
       onNext("second")
       subscribe { it -> Log.d("#1", it) }
       onNext("third")
       subscribe { it -> Log.d("#2", it) }
       onNext("fourth")
       subscribe { it -> Log.d("#3", it) }
       onComplete()
     }

 


 

📍 BehaviorSubject

BehaviorSubject

 

• 구독을 시작하면 가장 최근의 데이터를 발행한 후 그 후에 발행되는 항목들은 그대로 발행합니다 

만약 최근 데이터가 없다면 (처음 값 or default)를 발행합니다 

 에러가 발생한다면 어떠한 데이터도 전달하지 않고, 에러만 전달합니다 

 

val behaviorSubject : BehaviorSubject<String> = BehaviorSubject.createDefault("default Value")
    behaviorSubject.apply {
        subscribe {
           Log.d("BehaviorSubject #1", it)
        }

        onNext("Kotlin")
        onNext("Java")
        onNext("Flutter")
        subscribe {
           Log.d("BehaviorSubject #2", it)
        }
        
        onNext("Python")
        onNext("C++")
        subscribe {
            Log.d("BehaviorSubject #3", it)
        }
     }

 

 


 

📍 PublishSubject

publishSubject

 

• 구독 시점 이후 방출되는 아이템만 발행합니다 (Hot Observable)

subject 생성 시점, 구독 시점의 차이로 인해 데이터를 손실할 위험이 있습니다

    ▶️  Cold Observable로 만들거나 ReplaySubject을 사용해야합니다 

• 에러가 발생한다면 어떠한 데이터도 전달하지 않고, 에러만 전달합니다 

 

val publishSubject : PublishSubject<String> = PublishSubject.create()
publishSubject.apply {
   onNext("aaa")
   onNext("bbb")
   onNext("ccc")
   subscribe { Log.d("publishSubject #1", it) }
   
   onNext("AAA")
   onNext("BBB")
   subscribe { Log.d("publishSubject #2", it) }
   
   onNext("CCC")
   onComplete()
}

 


 

📍 ReplaySubject

ReplaySubject

 

• 구독을 시작하면 발행되었던 모든 데이터를 다시 발행합니다 

• 메모리 누수를 주의해야 합니다 

 

val replaySubject : ReplaySubject<String> = ReplaySubject.create()
replaySubject.apply {
   onNext("공지사항 1")
   subscribe { Log.d("replaySubject #1", it) }
   
   onNext("공지사항 2")
   onNext("공지사항 3")
   subscribe { Log.d("replaySubject #2", it) }
   
   onNext("공지사항 4")
   onNext("공지사항 5")
   subscribe { Log.d("replaySubject #3", it) }
   onComplete()
}

 

 

[참고자료]

https://reactivex.io/documentation/subject.html

 

ReactiveX - Subject

If you have a Subject and you want to pass it along to some other agent without exposing its Subscriber interface, you can mask it by calling its asObservable method, which will return the Subject as a pure Observable. See Also

reactivex.io

 


궁금하신 점이나 의견이 있으시면 댓글 부탁드립니다 감사합니다 😊