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

RXSwift中作为loading的BehaviorRelay返回值异常,状态未按预期从true变为false

问题成因

  1. response流逻辑错误:你定义response时在flatMap闭包中拿到请求返回的stories后,没有返回当前结果的Observable,反而重复返回了request流。单次触发请求的场景下request只会发射一次事件,导致response永远不会触发,response.map{_ in false}的逻辑永远不会执行,loading无法回到false。
  2. loading状态赋值时机颠倒:你现在用request.map{_ in true}来设置loading为true,request发射next事件的时机是请求成功返回时,相当于你请求结束才把loading设为true,完全不符合预期,也进一步打乱了状态流转。
  3. 错误处理逻辑位置错误:你把request的错误处理写在了flatMap内部,导致请求失败时errorSubject不会触发,error.map{_ in false}的逻辑也无法执行,即使请求失败loading也卡住在true状态。

修复方案

替换你ViewModel的init方法中的所有流处理代码即可:

override init() {
    super.init()
    
    // 刷新请求流
    let refreshAction = refreshTrigger
        .withLatestFrom(loading)
        .filter { !$0 }
        .do(onNext: { [weak self] _ in
            guard let self = self else { return }
            self.offset = 0
            self.loading.accept(true)
        })
        .flatMapLatest { [weak self] _ -> Observable<[Story]> in
            guard let self = self else { return .empty() }
            return self.fetchStories(type: self.selectedFeedType.value, offset: self.offset)
                .catch { error in
                    self.error.onNext(error.localizedDescription)
                    return .empty()
                }
        }
    
    // 加载更多请求流
    let loadMoreAction = loadMoreTrigger
        .withLatestFrom(loading)
        .filter { !$0 }
        .do(onNext: { [weak self] _ in
            guard let self = self else { return }
            self.offset += 10
            self.loading.accept(true)
        })
        .flatMapLatest { [weak self] _ -> Observable<[Story]> in
            guard let self = self else { return .empty() }
            return self.fetchStories(type: self.selectedFeedType.value, offset: self.offset)
                .catch { error in
                    self.error.onNext(error.localizedDescription)
                    return .empty()
                }
        }
    
    // 处理请求结果,更新列表数据
    Observable.merge(refreshAction, loadMoreAction)
        .subscribe(onNext: { [weak self] newStories in
            guard let self = self else { return }
            if self.offset == 0 {
                self.stories.accept(newStories)
            } else {
                self.stories.accept(self.stories.value + newStories)
            }
            self.loading.accept(false)
        })
        .disposed(by: disposeBag)
    
    // 请求错误时结束加载状态
    error.subscribe(onNext: { [weak self] _ in
        self?.loading.accept(false)
    })
    .disposed(by: disposeBag)
}

修复后逻辑更清晰,状态流转也符合预期:触发请求时立刻设loading为true,请求成功/失败都将loading设为false。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 06:21:01