RxSwift - 使用 maxCount 重试网络请求直到成功
Posted
技术标签:
【中文标题】RxSwift - 使用 maxCount 重试网络请求直到成功【英文标题】:RxSwift - Retry network request with maxCount until success 【发布时间】:2018-02-11 09:53:18 【问题描述】:如何使用 maxCount 重试网络请求(某种失败),例如。 5 次或直到服务器使用 RxSwift 的 retry
运算符返回我想要的内容。
我应该做的是:
-
当成功变为“ok”时,停止重试并立即发出
queryedSuccess
当成功仍然“失败”时,继续重试直到 maxCount 达到 5 并发出 queryedFail
服务器返回的 JSON 结构如下:
struct QueryAlipayOrderEnvelope
var success: String // "ok" or "fail"
var tradeNumber: String
这是我尝试做的:
struct ViewModel
var viewWillAppearTrigger = PublishSubject<Void>()
var rechargeTrigger = PublishSubject<Void>()
var outTradeNumber = PublishSubject<String>()
var queryedSuccess: Driver<QueryAlipayOrderEnvelope>
var queryedFail: Driver<QueryAlipayOrderEnvelope>
let queryResult = self.outTradeNumber.asObservable()
.flatMapLatest tradeNum in
AppEnvironment.current.apiService.queryAlipayOrder(outTradeNumber: tradeNum).materialize().debug("queryAlipayOrder", trimOutput: true)
.share(replay: 1)
.retry(5)
self.queryedSuccess = queryResult
.elements()
.skipWhile $0.success != "ok"
.takeLast(1)
.asDriver(onErrorDriveWith: .never())
.debug("queryedSuccess", trimOutput: true)
// this will emit when all 5 `success` are `fail`
self.queryedFail = queryResult
.elements()
.takeLast(1)
.filter $0.success != "ok"
.asDriver(onErrorDriveWith: .never())
.debug("queryedFail", trimOutput: true)
但是,请求只调用了一次,并且没有任何重试就被释放了。
【问题讨论】:
share
可能是这里的罪魁祸首。你需要吗?
@Cristik 如果我删除share
,将为每个订阅者调用请求。(所以这不是这里的问题。)
【参考方案1】:
Retry 运算符响应onError
通知。因为您在flatMapLatest
中使用materialize()
,所以您将Observable<Element>
转换为Observable<Event<Element>>
,这意味着您正在接收告诉您这是错误事件的元素,而不是接收onError
通知。
尝试删除materialize()
,看看是否有帮助。
【讨论】:
谢谢,但不幸的是,这仍然行不通。 因此删除 materialize() 将收到错误并触发重试。如何添加中间层以返回错误,以便请求在需要时抛出错误?因为我需要检查success
标识符
好吧,AppEnvironment.current.apiService.queryAlipayOrder
应该返回一个可以出错的 Observable。看这里:netguru.co/codestories/networking-with-rxswiftit以上是关于RxSwift - 使用 maxCount 重试网络请求直到成功的主要内容,如果未能解决你的问题,请参考以下文章