subject에 대해 공부하던 중 흥미로운 글을 발견했다. [RxSwift] Observer 숨겨진 observer를 찾는 글이었다. 그 동안은 subscribe이 당연히 Observer 인 줄 알았는데 생각해보니 Observer는 도대체 어디있는건가 .... ??!
ReactiveX Docs를 보면 이렇게 나와있다.
ReactiveX에서 옵저버는 Observable을 구독한다. Obseravable이 배출하는 하나 또는 연속된 항목에 옵저버는 반응한다.
Observer는 Observable을 구독(subscribe)한다 인데 밑에 코드를 보면 진짜 Observer가 없긴 하다 😅
observable // observable 여깄음
.subscribe(onNext:{ // subscribe 여깄음
print($0)
})
.disposed(by: disposeBag)
그럼 Observer는 어디 있냐면 바로 subscribe의 구현부에 있었다.
public func subscribe(
onNext: ((Element) -> Void)? = nil,
onError: ((Swift.Error) -> Void)? = nil,
onCompleted: (() -> Void)? = nil,
onDisposed: (() -> Void)? = nil
) -> Disposable {
let disposable: Disposable
if let disposed = onDisposed {
disposable = Disposables.create(with: disposed)
}
else {
disposable = Disposables.create()
}
#if DEBUG
let synchronizationTracker = SynchronizationTracker()
#endif
let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
// observer 생성
let observer = AnonymousObserver<Element> { event in
#if DEBUG
synchronizationTracker.register(synchronizationErrorMessage: .default)
defer { synchronizationTracker.unregister() }
#endif
switch event {
case .next(let value):
onNext?(value)
case .error(let error):
if let onError = onError {
onError(error)
}
else {
Hooks.defaultErrorHandler(callStack, error)
}
disposable.dispose()
case .completed:
onCompleted?()
disposable.dispose()
}
}
return Disposables.create(
self.asObservable().subscribe(observer),
disposable
)
}
subscribe하면 observer 를 자체적으로 생성하고 있었던 거였음 ... ㅋ
최종적으로 이 코드를 보자.
return Disposables.create(
self.asObservable().subscribe(observer),
disposable)
asOBservable()은 ObservableType을 Observable로 변환 시켜주는 함수라고 한다. 결국
asObservable().subscribe(observer) 이 코드를 통해 " Observer는 Observable을 구독(subscribe)한다. " 이 문장이 완성 된 것이다 😅
결국 Observable을 subscribe하면 subscribe 내부에서 Observer를 생성하고 생성한 Observable을 Observer가 구독하고 그 값(disposable)을 반환하는 것이다. 맞나 ... ?!
[RxSwift] Subject를 참고하였습니다.
원래 알고 싶었던 것은 이것 .. ! Subject 가 Observable + Observer 라는 사실은 코드 상으로 이해는 됐는데 말로 표현하라면 설명 불가 였다.
let randomNumGenerator = Observable<Int>.create{ observer in
observer.onNext(Int.random(in: 0 ..< 100))
return Disposables.create()
}
randomNumGenerator.subscribe(onNext: { (element) in
print("\(element)")
})
randomNumGenerator.subscribe(onNext: { (element) in
print("\(element)")
})
위 코드는 Observable을 사용한 것이다. 과연 같은 값을 print 할까 ..? 결론은 아니다. " Observable은 단지 하나의 함수이기 때문에 어떤 상태도 가지지 않으므로 모든 새로운 Observer에 대해 관찰 가능한 create 코드를 반복해서 실행한다. " 라고 한다. Observable은 어떤 상태를 갖고 있지 않기 때문에 그냥 하나의 함수를 두 번 실행한 것과 같은 거다. 그러니 보통은 다른 값을 print 할거다.
let randomNumGenerator = BehaviorSubject(value: 0)
randomNumGenerator.onNext(Int.random(in: 0..<100))
randomNumGenerator.subscribe(onNext: { (element) in
print("\(element)")
})
randomNumGenerator.subscribe(onNext: { (element) in
print("\(element)")
})
위 코드는 Subject를 사용한 것이다. Observable은 State를 갖고 있지 않는 반면 Subject는 State를 갖고있다. " Subject는 관찰자 세부 정보를 저장하고 코드를 한 번만 실행하고 모든 관찰자에게 결과를 제공한다. " 관찰자 세부 정보를 저장하기 때문에 자기를 구독한 사람에게 결국 같은 값을 쏴주므로 같은 값을 출력할거다.
Observable과 Subject의 차이는 이렇다. 그럼 Subject = Observer + Observable은 무슨 의미일까 ?
public final class BehaviorSubject<Element>
: Observable<Element>
, SubjectType
, ObserverType
}
벌써 답을 구했다. Subject는 Observable과 ObserverType을 따른다...
ObserverType을 따르므로 onNext, onCompleted, onError 와 같이 on 메서드를 동작시킬 수 있는것이다 !!
[RxSwift] Subject 이 글을 보며 공부해봤다. 내용이 아주 알찼다 👍🏻 👍🏻
솔직히 아직 다 이해는 가지 않지만 그래도 한 3분의 2 정도는 이해 한 것 같다. 😅 Rx 만든 사람 천재 아닌가 .. 🧐