RXSwift中合并isRefreshing与isLoadingMore两个Observable并触发带参API调用的实现方法咨询
在RxSwift中触发事件时获取多个Observable的最新值
嘿,刚接触RxSwift的话,这个需求确实容易卡壳——要在loadPageTrigger触发时拿到另外两个状态的当前值来调用方法,核心就是用**combineLatest + withLatestFrom**的组合,我给你一步步理清楚:
先明确你的现有代码场景
你的ViewModel里有这些Subject:
let feedItems: BehaviorSubject<[FeedItem]> = BehaviorSubject(value: [FeedItem]()) let isLoadingMore: PublishSubject<Bool> = PublishSubject() let loadPageTrigger: PublishSubject<Void> = PublishSubject() let isRefreshing: PublishSubject<Bool> = PublishSubject() func fetchFeed(showLoading: Bool = false, loadMore: Bool = false) { // API调用完成后设置self.feedItems.onNext(response) }
在初始化里你想监听loadPageTrigger,但不知道怎么拿到isRefreshing和isLoadingMore的当前值:
override init() { super.init() loadPageTrigger.subscribe(onNext: { // 需要获取isRefreshing和isLoadingMore的值,传入fetchFeed的参数中 self.fetchFeed() }).disposed(by: disposeBag) }
解决方案:用combineLatest合并状态,withLatestFrom触发时取值
首先有个小前提:isRefreshing和isLoadingMore用PublishSubject的话,第一次触发时可能拿不到初始值(因为它不会保存初始状态),所以建议改成BehaviorSubject,给个默认的false:
// 改成BehaviorSubject,确保有初始状态 let isLoadingMore: BehaviorSubject<Bool> = BehaviorSubject(value: false) let isRefreshing: BehaviorSubject<Bool> = BehaviorSubject(value: false)
然后修改你的初始化代码,合并两个状态并在触发时获取:
override init() { super.init() // 合并isRefreshing和isLoadingMore的最新状态为一个元组 let combinedStates = Observable.combineLatest(isRefreshing, isLoadingMore) .map { isRefreshingVal, isLoadingMoreVal in (isRefreshing: isRefreshingVal, isLoadingMore: isLoadingMoreVal) } // 当loadPageTrigger触发时,获取combinedStates的最新值 loadPageTrigger .withLatestFrom(combinedStates) .subscribe(onNext: { [weak self] states in // 根据你的业务逻辑设置showLoading参数,比如刷新时显示加载,加载更多按需调整 let shouldShowLoading = states.isRefreshing self?.fetchFeed(showLoading: shouldShowLoading, loadMore: states.isLoadingMore) }) .disposed(by: disposeBag) }
为什么这么做?
combineLatest:会持续监听isRefreshing和isLoadingMore的变化,每次其中一个发出新值时,就把两者的最新值组合成一个元组。withLatestFrom:只有当loadPageTrigger发出事件时,才会去取combinedStates的最新值,完美匹配你的需求——“触发时获取当前状态”。
这样每次loadPageTrigger被触发(比如滚动到底部或者下拉刷新触发),就能准确拿到当前的isRefreshing和isLoadingMore状态,传入fetchFeed方法里了。
内容的提问来源于stack exchange,提问作者Bobby Redjeans
相关产品推荐
相关产品推荐

