错误处理操作符 - ErrorHandling Operator

catchError

catchError 操作符将会拦截一个 error 事件,将它替换成其他的元素或者一组元素,然后传递给观察者。这样可以使得 Observable 正常结束,或者根本都不需要结束。

eg:

func catchError() {
    let recoverObservable = Observable<String>.just("Recover Error")
    getErrorObservable()
        .catchError({ (error) -> Observable<String> in
            print("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
            error.printLog()
            print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n")
            return recoverObservable
        })
        .debug("catchError")
        .subscribe()
        .disposed(by: disposeBag)
}

输出如下:

2017-12-27 13:50:58.068: catchError -> subscribed
2017-12-27 13:50:59.070: catchError -> Event next(1️⃣)
2017-12-27 13:51:00.070: catchError -> Event next(2️⃣)

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
10
Test
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

2017-12-27 13:51:01.070: catchError -> Event next(Recover Error)
2017-12-27 13:51:01.070: catchError -> Event completed
2017-12-27 13:51:01.070: catchError -> isDisposed

catchErrorJustReturn

catchErrorJustReturn 操作符会将 error 事件替换成其他的一个元素,然后结束该序列。

eg:

func catchErrorJustReturn() {
    getErrorObservable()
        .catchErrorJustReturn("Recover Error")
        .debug("catchErrorJustReturn")
        .subscribe()
        .disposed(by: disposeBag)
}

输出如下:

2017-12-27 13:53:16.850: catchErrorJustReturn -> subscribed
2017-12-27 13:53:17.854: catchErrorJustReturn -> Event next(1️⃣)
2017-12-27 13:53:18.852: catchErrorJustReturn -> Event next(2️⃣)
2017-12-27 13:53:19.854: catchErrorJustReturn -> Event next(Recover Error)
2017-12-27 13:53:19.854: catchErrorJustReturn -> Event completed
2017-12-27 13:53:19.854: catchErrorJustReturn -> isDisposed

retry

如果源 Observable 产生一个错误事件,重新对它进行订阅,希望它不会再次产生错误 retry 操作符将不会将 error 事件,传递给观察者。

然而,它会从新订阅源 Observable,给这个 Observable 一个重试的机会,让它有机会不产生 error 事件。

retry 总是对观察者发出 next 事件,即便源序列产生了一个 error 事件,所以这样可能会产生重复的元素。

func retry() {
    let observable = Observable<Int>.create { (observer) -> Disposable in
        if arc4random() % 10 == 0 {
            observer.onNext(1)
        } else {
            let error = TError.init(errorCode: 10, errorString: "Random Error", errorData: nil)
            observer.onError(error)
        }
        return Disposables.create()
    }
    observable
        .debug("Befor Retry")
        .retry()
        .debug("After Retry")
        .subscribe()
        .disposed(by: disposeBag)
}

输出如下:

2017-12-27 13:56:42.068: After Retry -> subscribed
2017-12-27 13:56:42.068: Befor Retry -> subscribed
2017-12-27 13:56:42.068: Befor Retry -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:56:42.068: Befor Retry -> isDisposed
2017-12-27 13:56:42.068: Befor Retry -> subscribed
2017-12-27 13:56:42.068: Befor Retry -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:56:42.069: Befor Retry -> isDisposed
2017-12-27 13:56:42.069: Befor Retry -> subscribed
2017-12-27 13:56:42.069: Befor Retry -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:56:42.069: Befor Retry -> isDisposed
2017-12-27 13:56:42.069: Befor Retry -> subscribed
2017-12-27 13:56:42.069: Befor Retry -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:56:42.069: Befor Retry -> isDisposed
2017-12-27 13:56:42.069: Befor Retry -> subscribed
2017-12-27 13:56:42.069: Befor Retry -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:56:42.069: Befor Retry -> isDisposed
2017-12-27 13:56:42.069: Befor Retry -> subscribed
2017-12-27 13:56:42.069: Befor Retry -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:56:42.069: Befor Retry -> isDisposed
2017-12-27 13:56:42.069: Befor Retry -> subscribed
2017-12-27 13:56:42.070: Befor Retry -> Event next(1)
2017-12-27 13:56:42.070: After Retry -> Event next(1)

retryWhen

这个操作符主要描述应该在何时重试,并且通过闭包里面返回的 Observable 来控制重试的时机:

闭包里面的参数是 Observable<Error> 也就是所产生错误的序列,然后返回值是一个 Observable

  • 当这个返回的 Observable 发出一个元素时,就进行重试操作。
  • 当它发出一个 error 或者 completed 事件时,就不会重试,并且将这个事件传递给到后面的观察者。
func retryWhen() {
    let observable = Observable<Int>.create { (observer) -> Disposable in
        if arc4random() % 10 == 0 {
            observer.onNext(1)
        } else {
            let error = TError.init(errorCode: 10, errorString: "Random Error", errorData: nil)
            observer.onError(error)
        }
        return Disposables.create()
    }

    let retryDelay: RxTimeInterval = 1.0
    let maxRetryCount: Int = 4
    observable
        .debug("Befor RetryWhen")
        .retryWhen({ (rxError) -> Observable<Int> in
            return rxError.enumerated().flatMap({ (index, element) -> Observable<Int> in
                if index >= maxRetryCount {
                    let err = TError.init(errorCode: 0, errorString: "Retry Too Many Times", errorData: nil)
                    return Observable.error(err)
                }
                return Observable.timer(retryDelay, scheduler: MainScheduler.instance)
            })
        })
        .debug("After RetryWhen")
        .subscribe()
        .disposed(by: disposeBag)
}

输出如下:

2017-12-27 13:59:37.270: After RetryWhen -> subscribed
2017-12-27 13:59:37.270: Befor RetryWhen -> subscribed
2017-12-27 13:59:37.270: Befor RetryWhen -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:59:37.271: Befor RetryWhen -> isDisposed
2017-12-27 13:59:38.271: Befor RetryWhen -> subscribed
2017-12-27 13:59:38.272: Befor RetryWhen -> Event error(TError(errorCode: 10, errorString: "Random Error", errorData: nil))
2017-12-27 13:59:38.272: Befor RetryWhen -> isDisposed
2017-12-27 13:59:39.273: Befor RetryWhen -> subscribed
2017-12-27 13:59:39.273: Befor RetryWhen -> Event next(1)
2017-12-27 13:59:39.273: After RetryWhen -> Event next(1)

results matching ""

    No results matching ""