Development/RxSwift
RxSwift) Error Handling (retry, retry(when:))
Tunko
2022. 6. 10. 13:42
retry
retry연산자는 옵저버블에서 에러가 발생하면 현재 시퀀스를 중단하고 다시 새로운 구독을 시작합니다.
새롭게 구독하는것이므로 기존에 있던 next이벤트들은 소멸되고 다시 시작합니다.
retry 연산자 함수 원형
public func retry() -> Observable<Element> {
CatchSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()))
}
public func retry(_ maxAttemptCount: Int)
-> Observable<Element> {
CatchSequence(sources: Swift.repeatElement(self.asObservable(), count: maxAttemptCount))
}
함수 원형을 보시면 두가지 케이스가 있습니다.
retry 연산자는 파라미터가 전달되지 않을시 계속 재시도를 하게 됩니다.
즉, 계속 에러가 나오게 되면 무한루프에 빠지게 되니 매우 위험합니다.
따라서 안전장치인 retry(_ maxAttemptCount: Int) 형태의 메소드도 구현되었습니다.
재시도 횟수에 제한을 걸어주는 retay메소드 입니다.
retry연산자는 Error가 발생하면 즉시 재시도를 합니다. 재시도 하는 시점을 컨트롤 할 수 없습니다.
에러가 발생하고 원하는 시점에 재시도를 하기위해선 retay연산자가 아닌 retry(when:) 연산자를 사용해야 합니다.
우선 retry 연산자를 보겠습니다.
let disposeBag = DisposeBag()
enum TunkoError: Error {
case error
}
var 재시도횟수 = 1
let source = Observable<Int>.create { observer in
let 현재재시도횟수 = 재시도횟수
print("현재재시도횟수\\(현재재시도횟수) 시작")
if 재시도횟수 < 5 {
observer.onError(TunkoError.error)
재시도횟수 += 1
}
observer.onNext(1)
observer.onNext(2)
observer.onCompleted()
return Disposables.create {
print("#\\(현재재시도횟수) 끝")
}
}
source
.retry()
.subscribe { print($0) }
.disposed(by: disposeBag)
출력
현재재시도횟수 [1] 시작
현재재시도횟수 [1] 끝
현재재시도횟수 [2] 시작
현재재시도횟수 [2] 끝
현재재시도횟수 [3] 시작
현재재시도횟수 [3] 끝
현재재시도횟수 [4] 시작
현재재시도횟수 [4] 끝
현재재시도횟수 [5] 시작
next(1)
next(2)
completed
현재재시도횟수 [5] 끝
retry(when: )
retryWhen은 클로저를 파라미터로 받아서 트리거 옵저버블을 리턴합니다. 그리고 리턴된 옵저버블에서 next이벤트가 발생하면 구독을 재시도하게 됩니다.
let disposeBag = DisposeBag()
enum TunkoError: Error {
case error
}
var 재시도횟수 = 1
let source = Observable<Int>.create { observer in
let 현재재시도횟수 = 재시도횟수
print("현재재시도횟수 [\\(현재재시도횟수)] 시작")
if 재시도횟수 < 5 {
observer.onError(TunkoError.error)
재시도횟수 += 1
}
observer.onNext(1)
observer.onNext(2)
observer.onCompleted()
return Disposables.create {
print("현재재시도횟수 [\\(현재재시도횟수)] 끝")
}
}
let trigger = PublishSubject<Void>()
source
.retry { _ in trigger}
.subscribe { print($0) }
.disposed(by: disposeBag)
print("--------------지금 재시도---------------")
trigger.onNext(())
trigger.onNext(())
trigger.onNext(())
trigger.onNext(())
출력
현재재시도횟수 [1] 시작
현재재시도횟수 [1] 끝
--------------지금 재시도---------------
현재재시도횟수 [2] 시작
현재재시도횟수 [2] 끝
현재재시도횟수 [3] 시작
현재재시도횟수 [3] 끝
현재재시도횟수 [4] 시작
현재재시도횟수 [4] 끝
현재재시도횟수 [5] 시작
next(1)
next(2)
completed
현재재시도횟수 [5] 끝
반응형