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&lt;Element&gt; 转换为Observable&lt;Event&lt;Element&gt;&gt;,这意味着您正在接收告诉您这是错误事件的元素,而不是接收onError 通知。

尝试删除materialize(),看看是否有帮助。

【讨论】:

谢谢,但不幸的是,这仍然行不通。 因此删除 materialize() 将收到错误并触发重试。如何添加中间层以返回错误,以便请求在需要时抛出错误?因为我需要检查success 标识符 好吧,AppEnvironment.current.apiService.queryAlipayOrder 应该返回一个可以出错的 Observable。看这里:netguru.co/codestories/networking-with-rxswiftit

以上是关于RxSwift - 使用 maxCount 重试网络请求直到成功的主要内容,如果未能解决你的问题,请参考以下文章

js助手函数

RxSwift 重试全链

重试延迟 - RxSwift

Alamofire/RxSwift 如何在状态码 401 上自动刷新令牌和重试请求

RxSwift 更新身份验证令牌

Moya rxswift : 刷新令牌并重启请求