RXSwift中作为loading的BehaviorRelay返回值异常,状态未按预期从true变为false
问题成因
- response流逻辑错误:你定义response时在
flatMap闭包中拿到请求返回的stories后,没有返回当前结果的Observable,反而重复返回了request流。单次触发请求的场景下request只会发射一次事件,导致response永远不会触发,response.map{_ in false}的逻辑永远不会执行,loading无法回到false。 - loading状态赋值时机颠倒:你现在用
request.map{_ in true}来设置loading为true,request发射next事件的时机是请求成功返回时,相当于你请求结束才把loading设为true,完全不符合预期,也进一步打乱了状态流转。 - 错误处理逻辑位置错误:你把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
相关产品推荐
相关产品推荐

