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

RxSwift中实现单次下载的正确方式是什么?附待验证代码

RxSwift 实现单次下载的正确方式

你的这段代码其实已经踩中了单次下载的核心逻辑,但可以在简洁性和健壮性上再优化一下,我来给你拆解说明:

先看你的代码的可取之处

  • 你已经用disposed(by: disposeBag)管理了订阅生命周期,避免内存泄漏,这一点很重要
  • 通过observeOn(MainScheduler.asyncInstance)确保UI更新在主线程,符合iOS的UI操作规范
  • 逻辑上是触发一次fetchNews请求,拿到结果后更新数据和页码,这本身就是单次下载的逻辑

可以优化的点

1. 简化弱引用的写法

RxSwift 现在支持在闭包里直接使用self?,不用手动转成strongSelf,代码会更清爽:

NewsAPI.fetchNews(page: loadedPage.value + 1)
    .observeOn(MainScheduler.asyncInstance)
    .bind(onNext: { [weak self] news in
        guard let self = self else { return }
        self.news.value += news
        self.loadedPage.value += 1
    })
    .disposed(by: disposeBag)

或者更简洁的可选链写法:

NewsAPI.fetchNews(page: loadedPage.value + 1)
    .observeOn(MainScheduler.asyncInstance)
    .bind(onNext: { [weak self] news in
        self?.news.value += news
        self?.loadedPage.value += 1
    })
    .disposed(by: disposeBag)

2. 必须加上错误处理

你的代码没有处理请求失败的情况,如果fetchNews抛出错误,整个订阅会触发onError但你没处理,可能导致崩溃或者用户看不到错误反馈。建议加上catch或者绑定onError:

NewsAPI.fetchNews(page: loadedPage.value + 1)
    .observeOn(MainScheduler.asyncInstance)
    .catch { error in
        // 这里处理错误,比如弹出提示、记录日志
        print("下载新闻失败:\(error.localizedDescription)")
        return Observable.empty() // 返回空序列,让订阅正常结束
    }
    .bind(onNext: { [weak self] news in
        self?.news.value += news
        self?.loadedPage.value += 1
    })
    .disposed(by: disposeBag)

或者直接在bind里处理onError:

NewsAPI.fetchNews(page: loadedPage.value + 1)
    .observeOn(MainScheduler.asyncInstance)
    .bind(
        onNext: { [weak self] news in
            self?.news.value += news
            self?.loadedPage.value += 1
        },
        onError: { error in
            print("下载新闻失败:\(error.localizedDescription)")
            // 这里可以添加UI提示,比如显示错误弹窗
        }
    )
    .disposed(by: disposeBag)

单次下载的核心要点

要确保这是单次下载,你需要注意:

  • 你的NewsAPI.fetchNews返回的Observable必须是单次执行的(也就是请求发送后,拿到响应就发送completed事件,不会持续发送数据),这通常网络请求的Observable都是这样实现的
  • 这段代码的触发时机是单次的(比如按钮点击一次执行一次,而不是无限订阅某个持续流)
  • 用disposeBag正确销毁订阅,避免重复请求或者内存泄漏

内容的提问来源于stack exchange,提问作者O. Shulzhenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:06:12