-
RxSwift - ObservableRxSwift 2021. 10. 30. 17:02
안녕하세요. 그린입니다🟢
이번 포스팅에서는 RxSwift의 Observable에 대해 학습해보겠습니다🧑🏻💻
그동안 RxSwift를 공부하면서 너무 중구난방으로 블로깅도하고 학습한 경향이 있는것같아요.
제가 RxSwift를 학습한지 얼마되지 않아서 체계가 없었나봅니다🥲
그래서 이번 기회에 RxSwift를 체계적으로 차근차근 다시 학습해보려합니다!🙌
그런 취지로 이번 특집의 첫타자는 Observable입니다.가장 중요하고 기본적으로 알고 있어야 다른것들의 학습이 병행될 수 있는 Observable!
같이 알아보시죠🙋🏻♂️
참고로 해당 학습 ReactiveX 공식문서들과 아래 링크를 통해 학습되었고 학습할 것입니다!
https://github.com/fimuxd/RxSwift/blob/master/Lectures/02_Observables/Ch2.%20Observables.md
Observable란?
Rx 세계에서는 Observer 즉 관찰자라고 하는것이 Observable을 subscribe(구독)합니다.
그러면 Observable이 Emit(방출)하는 이벤트나 이벤트 시퀀스에 반응하는 구조입니다.
즉 이 패턴으로 Observable이 이벤트를 방출할때까지 기다리거나 하지 않기에 비동기적 처리가 가능합니다.
그래서 요약하자면 Observable은 비동기적으로 어떠한 이벤트나 값을 생성하여 방출하는 역할을 합니다.
Marble Diagram
앞으로 Rx 세계에서 Observable의 이벤트 흐름에 대해 잘 설명할 수 있는것이 요 마블 다이어그램입니다!
시간 흐름에 따라 이벤트들의 값을 표기해주는 방식입니다.
즉 Observable과 Observable의 변환을 나타내줍니다.
앞으로 나올 참고할 이벤트 그림들은 다 마블 다이어그램을 가져옵니다!
아래 사이트를 참고해보시면 좋습니다🙌
Observable Life Cycle
Observable의 생명주기에는 3가지 요소로 되어 있습니다.
1. next
next를 방출해 다음 이벤트를 방출할 수 있습니다.
2. completed
이벤트들이 다 방출되면 completed를 방출하며 종료시킵니다.
3. error
도중 에러가 발생하면 error를 방출하며 종료됩니다.
Observable Create
Observable을 생성하는 방법에는 여러가지가 있습니다.
이를 각 종류마다 어떤 특성이 있는지 알아보겠습니다🙌
1. of
가변적인 단일요소 element를 가지는 Observable Sequence를 생성
let observable = Observable<String>.of("green", "blue", "red")
어레이가 아닌 String 타입입니다.
어레이를 넣어주게 되도 해당 어레이는 단일요소가 됩니다.
2. just
이름에서도 느껴지듯이 딱 하나의 element를 가지는 Observable Sequence를 생성
let observable = Observable<String>.just("Green")
3. from
of에서 어레이도 단일요소가 된다 했는데 from은 오로지 Array element만 받음
let observable = Observable<String>.from(["green", "blue", "red"])
4. empty
element를 가지지않고 completed 이벤트를 방출
let observable = Observable<Void>.empty()
Observable은 타입을 꼭 정의해줘야함으로 해당 empty를 사용할때는 컴파일러가 타입추론을 할 수 없음으로 Void로 지정
5. never
empty와의 차이는 never는 이벤트도 방출하지 않음
let observable = Observable<Any>.never()
6. range
Observable의 크기를 지정해주어 생성할 수 있음
let observable = Observable<Int>.range(start: 1, count: 3)
파라미터로는 시작 element인 1을 줄 수 있고 그 다음 몇개를 생성해줄지 count를 주어 생성해줍니다.
7. repeatElement
한번 방출하고 끝이 아닌 정해준 element를 지속적으로 emit해줌
let observable = Observable<String>.repeatElement("Green")
이러면 "Green" element를 계속 방출합니다.
8. interval
시간을 지정해줘 그 간격만큼 element를 방출
let observable = Observable<Int>.interval(2, scheduler:MainScheduler.instance)
해당 Observable을 통해 2초마다 특정한 이벤트를 방출할 수 있도록 해줍니다.
9. create
Observer에 직접적으로 이벤트를 방출
Observable<Int>.create({ (observer) -> Disposable in observer.onNext("Green") observer.onNext("Blue") observer.onCompleted() return Disposables.create() })
Observable 구독
위의 Observable 생성을 통해 시퀀스들을 만들어주었다.
이 시퀀스를 구독하고 실행할 수 있도록 해야한다.
왜나하면 해당 생성된건 그냥 말그대로 시퀀스일뿐이고 어딘가에서 이 Observable을 구독해야 이벤트를 방출합니다.
그전에는 아무 동작을 안합니다🚨
그럼 구독을 할 수 있도록 해줘봅시다!
subscribe()
해당 키워드로 구독해줍니다. 딱 용어만 봐도 구독이죠?!
let observable = Observable.of("Green", "Blue", "Red") observable.subscribe({ (event) in print(event) }) // next("Green") // next("Blue") // next("Red") // completed
위의 예시의 subscribe는 탈출 클로저로 String의 이벤트를 가지고 Disposable을 리턴해줍니다.
각 요소들을 subscribe하여 next 이벤트로 방출하고 끝난 후 completed 이벤트를 방출해줬습니다.
그런데 위의 주석을 보면 next이벤트까지 포함됩니다.
그럼으로 아래와 같이 해당 값만 프린트해볼 수 있습니다.
observable.subscribe { event in if let element = event.element { print(element) } } // Green // Blue // Red
subscribe(onNext:)
해당 위의 코드에서 next 이벤트들만 받고 나머지는 무시할때 쓰입니다.
또한 위의 코드가 너무 지저분하기에 아래와 같이 축약될 수 있습니다!
let observable = Observable.of("Green", "Blue", "Red") observable.subscribe(onNext: { (event) in print(event) })
Disposing & Terminating
1. dispose()
구독을 수동적으로 취소해 Observable을 종료시킵니다.
let observable = Observable.of("Green", "Blue", "Red") let names = observable.subscribe({ event in print(event) }) names.dispose()
해당 names의 dispose를 주어 구독을 취소하고 종료시켰습니다.
이후 발생되는 이벤트들은 정지됩니다.
2. DisposeBag()
위와 같이 매번 dispose를 수동적으로 주면서 관리하면 귀찮아지겠죠?
그럼으로 어느 한 가방에 담는다는 개념을 가져갈 수 있습니다.
이러한 구독취소들을 한 바구니에 담아 관리할 수 있습니다.
즉 DisposeBag 타입을 이용하는겁니다.
DisposeBag은 할당 해제하려할때 dispose()를 호출하는 disposables를 가지고 있습니다.
let disposeBag = DisposeBag() Observable.of("Green", "Blue", "Red") .subscribe({ (event) in print(event) }) .disposed(by: disposeBag)
subscribe를 통해서 방출되는 값들은 disposeBag에 담아 한번에 처리해줍니다.
Trait
Observable을 알아봤으니 더 옵션으로 Trait도 알아보겠습니다.
Trait은 Observable보다 적은 스코프의 Observable이라 생각하면 됩니다.
Observable이라는 큰 집합안의 부분집합 정도로 생각하면 되려나🤔
무튼 이 Trait으로 가독성을 높일 수 있습니다.
종류로는 3가지가 있습니다.
1. Single
싱글은 옵저버블의 특성인 존재하지 않는 범위에서 계속 임의적으로 연속된 이벤트를 방출하는것과 달리
매번 하나의 값 혹은 에러 둘중 하나만 방출합니다.
요 값들을 .success(value) / .error라 합니다.
.success(value)는 next와 completed의 결합입니다.
이 Single이 많이 사용되는 경우는 성공 혹은 실패의 명확한 프로세스이면서
1회성 프로세스인 데이터 다운로드 및 로딩과 같은 상황이 있습니다.
2. Maybe
Single과 Completable을 결합한것으로 성공 혹은 실패를 방출하면서 값도 방출할 수 있습니다.
즉, .success(value), .completed, .error를 가집니다.
파일에서 어떤 값을 읽어들여올때 사용해볼 수 있습니다.
3. Completable
말그대로 완료인지 실패인지만 방출하고 이벤트나 값을 방출하진 않습니다.
즉 .completed 혹은 .error를 가지는거죠.
파일쓰기 및 연산 등 값이 없어도 되는 성공과 실패의 경우 사용됩니다.
Debug
debug 연산자로 Observable의 이벤트들을 디버깅해볼 수 있으며 유용하게 사용됩니다.
observable .debug("Debug Test") .subscribe() .disposed(by: disposeBag)
간단하게 요런식으로 디버깅을 해볼 수 있습니다.
마무리
자 이렇게 오늘은 RxSwift에서 가장 기초이지만 가장 중요한! Observable에 대해 알아봤습니다🙌
처음 접하면 정말 어려운 개념이고 이해도 안되는게 당연한거에요😅
다음 시간에는 Subject라는 개념에 대해 알아보도록 하겠습니다🙌
[참고자료]
http://reactivex.io/documentation/observable.html
https://github.com/fimuxd/RxSwift/blob/master/Lectures/02_Observables/Ch2.%20Observables.md
https://jinshine.github.io/2019/01/02/RxSwift/2.Observable이란/
'RxSwift' 카테고리의 다른 글
RxSwift - Filtering Operators (0) 2021.11.08 RxSwift - Subject (0) 2021.11.03 RxSwift - Zip (0) 2021.10.13 RxSwift - Buffer & Window (0) 2021.10.06 RxSwfit - Debounce & Throttle (0) 2021.10.02