RxSwift 文档:Error Handling

Error Handling - 错误处理


一旦序列里面产出了一个 error 事件,整个序列将被终止。RxSwift 主要有两种错误处理机制:

  • retry - 重试
  • catch - 恢复

retryWhen

如果请求 JSON 失败,我们需要等待5秒后进行重试操作,重试4次如果全部失败则抛出错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 请求 JSON 失败时,等待 5 秒后重试,
// 重试 4 次后仍然失败,就将错误抛出

let maxRetryCount = 4 // 最多重试 4 次
let retryDelay: Double = 5 // 重试延时 5 秒

rxJson
.retryWhen { (rxError: Observable<Error>) -> Observable<Int> in
return rxError.flatMapWithIndex { (error, index) -> Observable<Int> in
guard index < maxRetryCount else {
return Observable.error(error)
}
return Observable<Int>.timer(retryDelay, scheduler: MainScheduler.instance)
}
}
.subscribe(...)
.disposed(by: disposeBag)

我们用 flatMapWithIndex 这个操作符,因为它可以给我们提供错误的索引数 index。然后用这个索引数判断是否超过最大重试数,如果超过了,就将错误抛出。如果没有超过,就等待 5 秒后重试。

Result

如果我们只是想给用户一个错误提示,我们可以自定义一个 Result 枚举来进行处理:

1
2
3
4
5
// 自定义一个枚举类型 Result
public enum Result<T> {
case success(T)
case failure(Swift.Error)
}

例如如下的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 当用户点击更新按钮时,
// 就立即取出修改后的用户信息。
// 然后发起网络请求,进行更新操作,
// 一旦操作失败就提示用户失败原因

updateUserInfoButton.rx.tap
.withLatestFrom(rxUserInfo)
.flatMapLatest { userInfo -> Observable<Void> in
return update(userInfo)
}
.observeOn(MainScheduler.instance)
.subscribe(onNext: {
print("用户信息更新成功")
}, onError: { error in
print("用户信息更新失败: \(error.localizedDescription)")
})
.disposed(by: disposeBag)

修改之后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
updateUserInfoButton.rx.tap
.withLatestFrom(rxUserInfo)
.flatMapLatest { userInfo -> Observable<Result<Void>> in
return update(userInfo)
.map(Result.success) // 转换成 Result
.catchError { error in Observable.just(Result.failure(error)) }
}
.observeOn(MainScheduler.instance)
.subscribe(onNext: { result in
switch result { // 处理 Result
case .success:
print("用户信息更新成功")
case .failure(let error):
print("用户信息更新失败: \(error.localizedDescription)")
}
})
.disposed(by: disposeBag)

这样我们的错误事件被包装成了 Result.failure(Error) 元素。