Observable이 던진 오류를 복구할 수 있도록 도와주는 연산자들 - Catch, Retry
안녕하세요 ◠‿◠ 고고입니다.
1. Catch
- Catch — 오류를 무시하고 배출되는 항목들을 계속 진행시켜 'onError'로부터 전달된 오류를 복구한다
구현부
public func `catch`(_ handler: @escaping (Swift.Error) throws -> Observable<Element>)
-> Observable<Element> {
Catch(source: self.asObservable(), handler: handler)
}
예시
let source = Observable<Int>.create { observer in
for count in 1...3 {
observer.on(.next(count))
}
let error = NSError(domain: "dummyError", code: 0, userInfo: nil)
observer.on(.error(error))
return Disposables.create {
print("disposed")
}
}
source.catch { error -> Observable<String> in
return Observable.just("Here is an error.")
}
.subscribe{ print($0) }
// 1
// 2
// 3
// Here is an error.
// disposed
- catchAndReturn (구 catchErrorJustReturn)
- catchAndReturn은 위와 같이 error가 발생했을때 설정해둔 단일 이벤트를 전달하도록 하는 연산자이다.
- subscribe에서 에러를 감지 하는 것이 아닌, Observable에서 에러에 대한 기본 이벤트를 설정하는 부분에 주목하자.
구현부
public func catchAndReturn(_ element: Element)
-> Observable<Element> {
Catch(source: self.asObservable(), handler: { _ in Observable.just(element) })
}
예시
let source = Observable<Int>.create { observer in
for count in 1...3 {
observer.on(.next(count))
}
let error = NSError(domain: "dummyError", code: 0, userInfo: nil)
observer.on(.error(error))
return Disposables.create {
print("disposed")
}
}.catchAndReturn(-1)
source
.subscribe{ print($0) }
// 1
// 2
// 3
// -1
// disposed
2. Retry
- Retry — 만약 소스 Observable이 'onError' 알림을 보낼 경우, 오류 없이 실행이 완료되기를 기대하며 재구독을 시도한다
구현부
public func retry() -> Observable<Element> {
CatchSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()))
}
예시
let source = Observable<Int>.create { observer in
for count in 1...3 {
observer.on(.next(count))
}
let error = NSError(domain: "dummyError", code: 0, userInfo: nil)
observer.on(.error(error))
return Disposables.create {
print("disposed")
}
}
source
.subscribe{ print($0) }
// 1
// 2
// 3
// 1
// 2
// 3
// ...
- retryWhen
- 재시도 하는 시점을 지정할 수 있고, 한번만 수행한다.
구현부
public func retry<TriggerObservable: ObservableType>(when notificationHandler: @escaping (Observable<Swift.Error>) -> TriggerObservable)
-> Observable<Element> {
RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler)
}
예시
let source = Observable<Int>.create { observer in
for count in 1...3 {
observer.on(.next(count))
}
let error = NSError(domain: "dummyError", code: 0, userInfo: nil)
observer.on(.error(error))
return Disposables.create {
print("disposed")
}
}
source
.retry(when: { err -> Observable<Int> in
return .timer(3, scheduler: MainScheduler.instance)
})
.subscribe{ print($0) }
// 1
// 2
// 3
// (3초 후...)
// 1
// 2
// 3
// completed
+)
3. Materialize, Dematerialize
- RxSwift 에서 쓰이는 Event Sequence를 제어할 수 있게 해준다.
- 보통 Materialize / Dematerialize 는 함께 사용한다.
- Observable을 분해할 수 있기 때문에 신중하게 사용해야 한다.
Materialize
- Sequence 를 Event<Element> Sequence로 변환한다.
구현부
public func materialize() -> Observable<Event<Element>> {
Materialize(source: self.asObservable())
}
Dematerialize
- Event<Element> Sequence 를 다시 Sequence로 변환한다.
구현부
public func dematerialize() -> Observable<Element.Element> {
Dematerialize(source: self.asObservable())
}
예시
let observable = Observable<Int>
.create { observer -> Disposable in
observer.onNext(1)
observer.onNext(2)
observer.onNext(3)
observer.onError(NSError(domain: "", code: 100, userInfo: nil))
observer.onError(NSError(domain: "", code: 200, userInfo: nil))
return Disposables.create { }
}
observable
.materialize()
.map { event -> Event<Int> in
switch event {
case .error:
return .next(999)
default:
return event
}
}
.dematerialize()
.subscribe { print($0) }
// next(1)
// next(2)
// next(3)
// next(999)
// completed
참고 : https://okanghoon.medium.com/rxswift-5-error-handling-example-9f15176d11fc
출처 : http://reactivex.io/documentation/ko/operators.html
'RxSwift' 카테고리의 다른 글
[RxSwift] Operators - 조건과 Boolean(7) (0) | 2021.11.29 |
---|---|
[RxSwift] Operators - 유틸리티(6) (0) | 2021.11.29 |
[RxSwift] Operators - 결합(4) (0) | 2021.11.20 |
[RxSwift] Operators - 필터링(3) (0) | 2021.11.19 |
[RxSwift] Operators - 변환(2) (0) | 2021.11.19 |
댓글