ReactiveX를 공부하다 보면 한 번쯤은 만나게 되는 개념 Hot&Cold Observable,
문서에서도 Observable설명하는 부분에서 대문짝만하게 적어놓은 걸 보니 중요한 개념인 듯싶어서 공부해 보았다!
단순하다면 단순한 개념이지만, ReactiveX에서 등장하는 다른 개념들과 복합적으로 생각하다 보면 이게 이해가 잘 된 건가.. 싶어서 보고 또 보고 해서 이해하는데 며칠이 걸렸다면 믿으시겠습니까..
https://reactivex.io/documentation/observable.html
ReactiveX - Observable
Observable In ReactiveX an observer subscribes to an Observable. Then that observer reacts to whatever item or sequence of items the Observable emits. This pattern facilitates concurrent operations because it does not need to block while waiting for the Ob
reactivex.io
그리고 공부할 당시에 Hot Observable/Cold Observable 이라는 개념과 multiCast, uniCast 이라는 개념이 어떻게 유기적으로 연결될 수 있는 건지 때문에 이해하느라 애먹었는데, 이 두 가지 개념이 어떤 관계를 가지고 있는지 이해한 대로 적어보려 합니다.
Hot Observable & Cold Observable
일단 어떤 걸 기준으로 이 두 가지 개념이 구분이 된 건지 먼저 알아야겠죠?
Observable 앞 수식어가 Hot, Cold인걸 보니 어떤 지점에서 두 개가 상반된 특징을 가지고 있는 것 같아요.
맞습니다.
시퀀스를 언제 방출하는지에 따라 구분을 해놓은 것입니다.
*시퀀스
- Infinite Sequence : 이벤트를 무한대로 방출할 수 있는 것
( 대부분 UI 관련된 이벤트 - 버튼 탭, 텍스트필드 입력)
- Finite Sequence : 한정적으로 방출할 수 있는 이벤트
공식문서에 적힌 내용을 아주 간단히만 정리하면,
- Hot Observable
- 생성되자마자 이벤트 방출 시킬 수 있는 Observable
- Cold Observable
- 이벤트를 방출하기 전에 관찰자(Observer)가 구독하기를 기다리는 Observable
Hot Observable
Hot Observable은 생성되자마자 이벤트를 방출시킬 수 있습니다. 즉, 구독을 하는가 하지 않는가에 영향을 받지 않고 이벤트를 방출할 수 있는 것이죠!
때문에, 관찰자가 구독을 하게 되면 구독 시점에 따라 해당 시점에 방출된 이벤트를 처리할 수 있겠죠? 관찰자의 입장에서는 Observable Sequence의 처음부터가 아니라 어느 중간지점부터 관찰할 수 있는 겁니다.
일상생활의 비유
- 생방송(Observable) : 사람들(Observer)이 방송을 보는지 안 보는지 중요하지 않고 각자가 방송을 켠 시점(구독한 시점)부터 계속 방송을 볼 수 있는 것
- 유튜버(Observable)는 계속 영상을 올리고 있지만 구독자(Observe)는 유튜브 구독 후에 알림을 계속 받을 수 있다.
RX에서 대표적인 예가 될 수 있는 것은 PublishSubject, BehaviorSubject입니다.
let hotSubject = PublishSubject<String>()
hotSubject.onNext("first") //📍구독 이전에도 이벤트 방출 가능 (onNext 가능)
hotSubject.onNext("second") //📍구독 이전에도 이벤트 방출 가능 (onNext 가능)
//📍 but, 구독 이후에 Observer는 시퀀스를 관찰하기 시작
hotSubject.subscribe { value in
print("hotSubject --> ", value)
}
.disposed(by: disposeBag)
hotSubject.onNext("third")
hotSubject.onNext("fourth")
multiCast와는 어떤 관계가 있나
위와 같은 Hot Observable의 특징을 바탕으로 여러 구독자에서 하나의 Observable stream을 공유받아 구독 이후 방출된 이벤트에 대한 처리를 하는 것입니다. 이러한 특성으로 인해 multicast와 같은 특성을 가질 수도 있는 것이죠!
즉 "Hot Observable은 무조건 multiCast이다." 라고 이해하기보다 "Hot Observable은 multicast와 같은 특성을 가질 수도 있는 Observable이다"라고 이해하는 게 좋겠습니다! :)
나중에 또 까먹고 다시 이 글 들어와서 읽을 나 자신을 위해 요약하자면🥲
* Hot Observable은 이벤트 방출 측면에서 구독을 기다리지 않음 -> 관찰자는 구독 후 시퀀스의 중간부터 관찰 가능 -> 여러 군데에서 구독해도 새로운 이벤트 스트림이 아니라 공유되고 있던 이벤트를 구독함 (multicast 특성)
Cold Observable
Cold Observable은 관찰자가 구독하기를 기다렸다가 구독을 해야 비로소 이벤트를 처음부터 방출하기 시작합니다.
그래서 관찰자가 시작부터의 모든 시퀀스를 관찰할 수 있도록 보장하는 Observable인 것이죠.
일상생활의 비유
- OTT 영상(Observable) : 사람들이 언제 방송을 켜든(언제 구독하든) 처음부터 영상을 시작한다.
RX에서는 여러 가지가 있지만 Single이나 just, from, of 등이 될 수 있습니다!
//hotObservable은 생성되자마자 구독의 유무에 관계 없이 이벤트를 방출할 수 있는 반면,
//coldObservable은 Observer가 구독하기 전까지 대기하고, 구독하면 그때 모든 이벤트들을 방출
//📍Single
let single = Single<String>.create { singleObserver in
singleObserver(.success("single success"))
return Disposables.create()
}
single
.subscribe{ value in
print("single subscribe1 -> ", value)
}
.disposed(by: disposeBag)
//single subscribe1 -> success("single success")
single
.subscribe{ value in
print("single subscribe2 -> ", value)
}
.disposed(by: disposeBag)
//single subscribe2 -> success("single success")
//📍 from
let from = Observable.from([1,2,3,4])
from
.subscribe { value in
print("from subscribe1 -> ", value)
}
.disposed(by: disposeBag)
// from subscribe1 -> next(1)
// from subscribe1 -> next(2)
// from subscribe1 -> next(3)
// from subscribe1 -> next(4)
// from subscribe1 -> completed
from
.subscribe { value in
print("from subscribe2 -> ", value)
}
.disposed(by: disposeBag)
// from subscribe2 -> next(1)
// from subscribe2 -> next(2)
// from subscribe2 -> next(3)
// from subscribe2 -> next(4)
// from subscribe2 -> completed
uniCast와는 어떤 관계가 있나?
구독을 해야 비로소 실행되는 Cold Observable의 특성으로 인해 unicast와 같이 각 구독마다 다른 이벤트 스트림이 생기는 특성을 가질 수 있는 것입니다!
어휴 .. hot, cold Observable로 Observable의 종류를 구분 지을 수 있고 이러한 Observable들이 multiCast 혹은 uniCast와 같은 특성을 가질 수 있는 것이네요. 자꾸 어떤 글에서 본 대로 ‘hot Observable은 multiCast이고 cold Observable은 uniCast이다. ‘ 라는 한 문장으로 이해하려니 머릿속에 안 들어왔던 것!
어떤 개념을 이해할 때 눈으로, 머리로는 이해가 되더라도 이걸 나만의 언어로 정리하려다 보니 이것도 네다섯 번은 같은 개념을 공부한 것 같댜..ㅎㅎㅎ 그래도 잘 이해하고 넘어가고 싶었던 ReactiveX의 개념들이 어느 정도 머리에 새겨진 것 같아 뿌듯!
'RxSwift' 카테고리의 다른 글
[RxSwift] 메모리 누수 일어나기 딱 좋은(?) .bind(with:onNext:) & 중첩 클로저의 객체 참조 (4) | 2024.09.09 |
---|---|
[RxSwift] Observable stream 에서 share가 필요한 이유 | multiCast, uniCast (0) | 2024.08.23 |