Observable
ํน์ Observable Sequence , Sequence์๋ ๊ฐ์ ๋ง์ด๋ค. ๊ด์ฐฐ ๊ฐ๋ฅํ ๊ฐ์ฒด์ด๋ฉฐ, ๊ตฌ๋
์๊ฐ ์ด๋ฅผ ๊ตฌ๋
ํ์ฌ “์ด๋ฒคํธ”๋ฅผ ๋ฐ์ ์ ์๋ค. ์ด๋ฒคํธ์๋ 3๊ฐ์ง ์ข
๋ฅ๊ฐ ์๋ค.
์ด๋ฒคํธ์ ์ ๋ฌ ๋ฐฉํฅ : Observable
-> Observer
์ด๋ฒคํธ์ ๊ด์ฐฐ ๋ฐฉํฅ : Observable
<- Observer
์ด๋ฒคํธ์ ์ข
๋ฅ
Observable์ 3๊ฐ์ง ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋
์์๊ฒ ์ ๋ฌํ๋๋ฐ, ๊ตฌ๋
์๋ ์ด๋ฅผ ๋ฐ์ ํด์ผํ ์ผ๋ค์ ์ฒ๋ฆฌํ๋ค.
- Next: Emission์ด๋ผ๊ณ ๋ ํ๋ฉฐ, ์์(๊ฐ)๋ค์ ๋ฐฉ์ถํ๋ค.
- Completed: Observable์ด “์๋ฌ ๋ฐ์ ์์ด ์ ์์ ์ผ๋ก ์ข
๋ฃ๋ ๋” ์ ๋ฌ๋๋ค. Observable์ ์๋ช
์ฃผ๊ธฐ๊ฐ ๋๋๋ค.
- Error: Observable์ด “์๋ฌ๋ก ์ธํด ์ข
๋ฃ๋ ๋” ์ ๋ฌ๋๋ค. Observable์ ์๋ช
์ฃผ๊ธฐ๊ฐ ๋๋๋ค.
Marble Diagram
https://rxmarbles.com
Observable์ ์์ฑ์์
1. Create ์ฐ์ฐ์๋ฅผ ์ด์ฉํ ์์ฑ
let observerble = Observable<Int>.create { (observer) -> Disposable in
observer(50)
observer(.next(100))
observer()
return Disposables.create()
}
2. From ์ฐ์ฐ์๋ฅผ ์ด์ฉํ ์์ฑ
let observerble2 = Observable<Int>.from([-50, -100])
SubScribe
Observable์ Observer์๊ฒ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ๋ค. ์ด ์ ๋ฌ๋๋ ์์ ์ observer๊ฐ observable์ subscribeํ๋ ์๊ฐ์ด๋ค. ์ฆ, ๊ด์ฐฐ(๊ตฌ๋
)์ ํ์ง ์์ผ๋ฉด ์ด๋ฒคํธ๋ ์ ๋ฌ๋์ง ์๋๋ค๋ ๋ง๊ณผ ๊ฐ๋ค.
let ob1 = Observable<Int>.create { (observer) -> Disposable in
observer.on(.next(0)) // ๊ตฌ๋
์์๊ฒ 0์ด๋ผ๋ ๊ฐ์ ์ ๋ฌํ๋ค.
observer.onNext(1) // ๊ตฌ๋
์์๊ฒ 1์ด๋ผ๋ ๊ฐ์ ์ ๋ฌํ๋ค.
observer.onCompleted() // Observable์ด ์ ์ ์ข
๋ฃ๋๋ฉฐ, ์๋ช
์ฃผ๊ธฐ๊ฐ ๋๋๋ค.
return Disposables.create()
}
ob1.subscribe { event in
print(event.element) // ์ด๋ ๊ฒ๋ ๊ฐ์ ์ ๊ทผํ ์ ์๋ค.
switch event{
case .next(let element):
print("element ->",element)
case .completed:
print("Completed!")
case .error(let error):
print(error)
}
}
๊ตฌ๋
์ ํ๊ฒ๋๋ฉด Event
๋ฅผ ์ ๋ฌ๋ฐ๊ฒ๋๊ณ , ์์์ ๋งํ๋ฏ์ด 3๊ฐ์ง ์ข
๋ฅ๊ฐ ์๊ธฐ ๋๋ฌธ์ switch๋ก ๋ถ๊ธฐํ ์ ์๋ค.
Switch๋ฌธ ๋ฐ์์ onNext๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ ์ง์ ์ ๊ทผํ๋ ค๋ฉด event.element
๋ก ์ ๊ทผํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ Subscribe(๊ด์ฐฐ)์ ํตํด ์ ๋ฌ๋ฐ๋ ์ด๋ฒคํธ๋ ํ๋ฒ์ ํ๋์ ์ด๋ฒคํธ๋ง ์ ๋ฌ๋ฐ๊ฒ๋๋ค.
Disposable
Observable๊ณผ ๊ด๋ จ๋ ๋ฆฌ์์ค๋ฅผ ์ ๋ฆฌํ๋ ์ฝ๋
var bag = DisposeBag()
let ob = Observable.from([1,2,3])
.subscribe { element in
print("onNext: \(element)")
} onError: { error in
print("Error: \(error)")
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("Disposed")
}.disposed(by: bag)
bag = DisposeBag()
์ฌ๊ธฐ์ Disposed๋ Observable์ด ์ ๋ฌํ๋ ์ด๋ฒคํธ๊ฐ ์๋๋ค. Observable๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๋ฆฌ์์ค๊ฐ ์ ๊ฑฐ๋ ํ์ Disposed ํด๋ก์ ๊ฐ ํธ์ถ๋๋ค.
Disposable ์ฉ๋
- Observable๊ณผ ๊ด๋ จ๋ ๋ฆฌ์์ค๋ค์ ์ ๋ฆฌํ๋๋ฐ ์ฌ์ฉ๋๋ค.
- ์คํ ์ทจ์์ ์ฌ์ฉ๋๋ค.
๋ง๋ค์ด๋จ๋ DisposeBag
ํ๋กํผํฐ์ ์๋ก์ด DisposeBag
๋ฅผ ๋ฃ์ผ๋ฉด bag์์ ์๋ Disposable๋ค์ด ํด์ ๋๋ค.
๋๋ ์ต์
๋๋ก ํด์ nil์ ๋ฃ์ด์ค๋ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค ์ ์๋ค.
Disposable์ ์คํ์ทจ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
// ์คํ ์ทจ์์ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ
let ob2 = Observable<Int>
.interval(.seconds(1), scheduler: MainScheduler.instance)
.subscribe { element in
print("onNext: \(element)")
if element == 3{
bag = DisposeBag()
}
} onError: { error in
print("Error: \(error)")
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("Disposed interval")
}.disposed(by: bag)
Operators (์ฐ์ฐ์)
Observable์ ์์ฑ, ๋ฐฉ์ถ, ํํฐ๋ง ๋ฑ์ ๋ค์ํ ๋ฉ์๋๋ค์ด ์๋๋ฐ ์ด๊ฒ๋ค์ ํตํ์ด Operators๋ผ๊ณ ํ๋ค.
Map, filter, take….. ๋ฑ ๊ฝค ์ฌ๋ฌ์ข
๋ฅ๊ฐ ์๋ค. ๋ง๋ธ ๋ค์ด์ด๊ทธ๋จ์ ํตํด์ ์๊ฐ์ ์ผ๋ก ํ์ธํ ์ ์๋ค.
RxMarbles: Interactive diagrams of Rx Observables
Take operator
Observable.from([1, 2, 3, 4, 5, 6, 7, 8, 9])
.take(5)
.subscribe { print($0) }
.disposed(by: bag)
Take operator๋ emit์ 5ํ ์คํํ๋ค.