You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用RxSwift实现每10秒发起网络请求并绑定数据到UITableView

实现RxSwift 10秒自动刷新列表的方案

你之前运行失败的核心原因大概率是两点:一是网络请求没有处理异常分支的事件发送,导致序列卡住;二是没有捕获单个请求的错误,一次失败就直接终止了整个定时序列。按照下方步骤调整代码即可实现需求:

1. 修正MarketService的异常事件处理

你当前的fetchMarkets方法中,状态码异常、返回数据为空的分支没有给观察者发送任何事件,会导致序列永久卡住,同时单次请求结束后需要主动发送完成事件避免内存泄漏,修正后代码如下:

class MarketService: MarketServiceProtocol  {
    // 自定义请求错误类型,方便上层识别异常场景
    enum RequestError: Error {
        case invalidStatusCode
        case emptyData
    }

    func fetchMarkets() -> Observable <[Market]> {
        return Observable.create { observer -> Disposable in
            RestManager.shared.makeRequest(withEndPoint: "market/v2/get-summary?region=US" , withHttpMethod: .get) { result in
                if let error = result.error {
                    observer.onError(error)
                    return
                }
                guard let response = result.response,
                      200 ... 299 ~= response.httpStatusCode else {
                    observer.onError(RequestError.invalidStatusCode)
                    return
                }
                guard let data = result.data else {
                    observer.onError(RequestError.emptyData)
                    return
                }
                do {
                    let decodedData = try JSONDecoder().decode(MarketResult.self, from: data)
                    observer.onNext(decodedData.marketSummaryAndSparkResponse.markets)
                    // 单次请求完成后发送结束事件
                    observer.onCompleted()
                } catch {
                    observer.onError(error)
                }
            }
            return Disposables.create { }
        }
    }
}

2. 改造ViewModel的fetchMarketViewModels方法

需要把定时序列和网络请求绑定,同时做错误隔离避免单次请求失败中断整个定时逻辑,示例代码如下:

func fetchMarketViewModels() -> Observable<[MarketCellViewModel]> {
    // timer的第一个参数设置为0,代表进入页面立刻发起第一次请求,不需要等10秒
    return Observable<Int>.timer(.seconds(0), period: .seconds(10), scheduler: MainScheduler.instance)
        .flatMapLatest { _ in
            return self.marketService.fetchMarkets()
                // 捕获单次请求的错误,不让它中断整个定时序列
                .catch { error in
                    print("接口请求失败:\(error.localizedDescription)")
                    // 错误时可根据业务需求返回空数组,或者返回本地缓存的旧数据
                    return Observable.just([])
                }
        }
        // 把网络返回的[Market]转换成你需要的CellViewModel数组
        .map { markets in
            markets.map { MarketCellViewModel(market: $0) }
        }
}
  • 这里用flatMapLatest而不是flatMap,如果上一次请求还没返回就触发了下一次定时,会自动取消上一次未完成的请求,避免旧数据覆盖新数据。
  • 如果你不需要进入页面立刻加载第一次数据,只需要每隔10秒触发请求,可以把timer替换为Observable<Int>.interval(.seconds(10), scheduler: MainScheduler.instance)。

3. ViewController绑定逻辑无需修改

你原有的UITableView绑定代码可以直接复用,不需要调整。


其他可选优化项:

  • 如果需要支持下拉刷新等手动刷新操作,可以把定时序列和手动刷新的Subject用merge合并,就能同时支持两种刷新逻辑
  • 如果需要页面退到后台暂停定时、回到前台恢复,可以监听App生命周期通知,进入后台时销毁当前序列,回到前台时重新绑定即可

内容的提问来源于stack exchange,提问作者Mat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:15:04