RxSwift

[RxSwift] BehaviorSubject, PublishSubject, ReplaySubject, AsyncSubject

yeggrrr🐼 2024. 6. 26. 23:27
728x90

 

[RxSwift] Observable & Observer (just, of, from, create)

RxSwfitReactive eXension + Swift비동기 프로그래밍을 직관적으로 작성할 수 있도록 도움을 주는 라이브러리RxSwift는 구독(Observe)을 해서 데이터 변화에 반응하기 때문에 비동기 처리를 쉽게 할 수 있도

yegenie-coding.tistory.com

Obseravable & Observer

Observable은 이벤트를 "전달"하는 녀석이고, Observer는 그 이벤트를 "처리"하는 녀석이다.
이벤트를 관찰하는 Observable를 구독(subscribe)을 하게 되면, 시간의 흐름에 따라 이벤트를 방출하게 된다.

하지만, Observable은 "전달만"할 수 있고, Observer는 "처리만"할 수 있기 때문에
이벤트 변경 사항을 Observer에게 전달해도 적용되지 않는다.

이때 알아야할것이 바로! 'Subject'이다.


Subject는 Observable과 Observer의 역할을 동시에 수행한다.

Subject는 총 4가지가 있다.

1. BehaviorSubject
2. PublishSubject
3. ReplaySubject
4. AsyncSubject


BehaviorSubject

- BehaviorSubject는 초기값이 필수이다.
- 구독(subscribe)이 발생하면, 발생한 가장 최신의 이벤트를 전달받는다. (발생한 값이 없다면, 초기값 전달)

let behaviorSubject = BehaviorSubject(value: "초기값아무거나")
behaviorSubject.onNext("두번째 값")
behaviorSubject.subscribe { value in // 구독
    print(value)
}
behaviorSubject.onNext("세번째 값")
// <실행 결과>
// next(두번째 값)
// next(세번째 값)

이처럼 최근에 전달된 이벤트 '하나'를 전달하기 때문에 구독 직전의 값과 이후의 값이 출력된다.
BehaviorSubject는 한번도 방출되지 않았을 경우를 대비해서 '초기값'을 선언해 놓는 것이다.

PublishSubject

publishSubject는 초기값이 없다.
구독(subscribe) 이후에 방출된 항목만 Observer에 전달된다. (구독 이전의 이벤트들은 무시)

let publishSubject = PublishSubject<String>()
publishSubject.onNext("첫 번째 값") // 무시
publishSubject.subscribe { value in // 구독
    print(value)
}
        
publishSubject.onNext("두 번째 값")
publishSubject.onNext("세 번째 값")
// <실행 결과>
// next(두번째 값)
// next(세번째 값)

ReplaySubject

최신 이벤트를 bufferSize에 맞게 저장해서
구독(subscribe)를 한 시점부터 저장한 이벤트를 모두 전달한다.

let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
replaySubject.onNext("첫 번째 값")
replaySubject.onNext("두 번째 값")
replaySubject.onNext("세 번째 값")
replaySubject.subscribe { value in
    print(value)
}
        
replaySubject.onNext("네 번째 값")
replaySubject.onNext("다섯 번째 값")
// <실행 결과>
// next(두 번째 값)
// next(세 번째 값)
// next(네 번째 값)
// next(다섯 번째 값)

설정해 놓은 bufferSize가 2이기 때문에, 가장 최근에 발생한 값 2개만 저장할 수 있다.
그래서 구독 직전의 2개의 값과 구독 이후의 값만 출력된 것을 확인할 수 있다.

ReplaySubject는 buffer의 크기를 직접 지정해주는 만큼 너무 많은 이벤트를 저장하게 되면,
메모리 부하가 발생할 수 있으므로 메모리 관리에 신경써야한다.


AsyncSubject

위 3개의 Subject는 구독(subscribe)를 기준으로 이벤트를 방출하는데,
AsyncSubject는 completed 이벤트가 발생하기 전까지 어떠한 이벤트도 방출되지 않는다.

completed가 전달되는 시점에서 가장 최신의 값을 방출한다.

let asyncSubject = AsyncSubject<String>()
asyncSubject.onNext("첫 번째 값")
asyncSubject.onNext("두 번째 값")
asyncSubject.subscribe { value in
    print(value)
}
asyncSubject.onNext("세 번째 값")
asyncSubject.onCompleted()
asyncSubject.onNext("네 번째 값")
asyncSubject.onNext("다섯 번째 값")
// <실행 결과>
// next(세 번째 값)
// completed

이처럼 구독과 상관없이 이벤트가 전달되지 않다가 onCompleted가 호출된 시점에서 가장 최신의 이벤트가 전달된다.


<BehaviorSubject>
초기값O
구독 시점에서 가장 최신 이벤트 하나를 전달
구독 이후에 방출된 이벤트 전달

<PublishSubject>
초기값X
구독 이후의 이벤트만 전달

<ReplaySubject>
bufferSize 만큼 저장 후, 구독 이후 저장한 이벤트 모두 전달
2개 이상의 이벤트를 저장하고 싶을 때 사용

<AsyncSubject>
구독과 상관없이 onCompleted 기준으로 가장 최근 값 하나를 전달

 

728x90

'RxSwift' 카테고리의 다른 글

[RxSwift] Single  (0) 2024.08.21
[RxSwift] Observable & Observer (just, of, from, create)  (0) 2024.06.24