gpt4 book ai didi

swift - 如何正确使用 switchLatest 在搜索结果和 tableview 的空状态之间切换?

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:53 26 4
gpt4 key购买 nike

我是 RxSwift 的新手,正在尝试处理在搜索自动完成的空状态和填充状态之间切换的任务。

我有一个驱动程序响应长度 > 0 的文本字段文本更改并发出网络请求,另一个驱动程序不是对空搜索查询进行过滤,而是用“收藏夹”填充 TableView 。我最初在两个可观察对象上使用了 merge() 但问题是快速清除文本会显示收藏夹但是当最后一个获取请求返回时它会合并并覆盖空状态。

我尝试切换到 switchLatest(),希望它能在触发最终的 clearResult 时取消之前的获取请求,但这个可观察对象似乎根本不会触发,我有点卡住了。任何帮助将不胜感激!

let queryFetchResultViewModel: Driver<[NewSearchResultViewModel]>  = queryText
.filter { $0.utf8.count > 0 }
.throttle(0.5, scheduler: MainScheduler.instance)
.flatMapLatest { query in
appContext.placeStore.fetchPredictions(withQuery: query)
}
.map { $0.map { NewSearchResultViewModel.prediction(prediction: $0) } }
.asDriver(onErrorJustReturn: [])

let queryClearResultViewModel: Driver<[NewSearchResultViewModel]> = queryText
.filter { $0.utf8.count == 0 }
.withLatestFrom(favoritePlaces.asObservable())
.map { places in places.map(NewSearchResultViewModel.place) }
.asDriver(onErrorJustReturn: [])

searchResultViewModel = Driver.of(queryFetchResultViewModel, queryClearResultViewModel).switchLatest()

最佳答案

您期望空字符串会影响显式过滤掉空字符串的流的输出。这就是您遇到此问题的原因。

--编辑--

为了更好地解释以上...假设用户键入一个字符,然后在您的原始代码中将其删除。这就是将要发生的事情:角色将进入 queryClearResultViewModelfilter 并被过滤掉。它还将遍历 queryFetchResultViewModel 链并获取预测。然后用户删除将进入 queryFetchResultViewModel 过滤器的字符并停止,同时它会一直通过 queryClearResultViewModelsearchResultViewModel 将获得最喜欢的地方...

然后网络请求完成,将预测结果传递给 searchResultViewModel

此时,switchLatest 将关闭 queryClearResultViewModel(它将停止监听)并显示查询结果。它现在已停止收听清晰的结果流,因此不会再显示更多收藏夹。

-- 结束编辑--

这是将执行您想要的操作的代码:

searchResultViewModel = queryText
.throttle(0.5, scheduler: MainScheduler.instance)
.flatMapLatest { query -> Observable<[NewSearchResultViewModel]> in
if query.isEmpty {
return favoritePlaces.asObservable()
.map { $0.map(NewSearchResultViewModel.place) }
}
else {
return appContext.placeStore.fetchPredictions(withQuery: query)
.map { $0.map { NewSearchResultViewModel.prediction(prediction: $0) } }
}
}
.asDriver(onErrorJustReturn: [])

上面的代码之所以有效,是因为 flatMapLatest 会在新查询进入时取消正在进行的 fetchPredictions(withQuery:) 调用。即使该查询为空。

如果您打算将 queryText 分成两个流,然后重新组合它们,那么您需要做的就是让 queryFetchResultViewModel 处理空文本通过在空查询通过时发出 Observable.empty()。但即使在那里,您也可能会遇到竞争问题,因为获取正在受到限制,而清除却没有。因此,您可能会遇到以下情况:提取开始,空查询通过显示收藏夹,然后查询完成显示结果,然后提取流接收(延迟的)清除并且不执行任何操作,因为查询已经完成.所以你必须限制清晰的流和获取流......

所以像这样(我使用 debounce 因为我认为它更适合这类事情):

let debouncedQuery = queryText.debounce(0.5, scheduler: MainScheduler.instance)

let queryFetchResultViewModel = debouncedQuery
.flatMapLatest { query -> Observable<[String]> in
guard !query.isEmpty else { return Observable.empty() }
return appContext.placeStore.fetchPredictions(withQuery: query)
}
.map { $0.map { NewSearchResultViewModel.prediction(prediction: $0) } }
.asDriver(onErrorJustReturn: [])

let queryClearResultViewModel = debouncedQuery
.filter { $0.isEmpty }
.withLatestFrom(favoritePlaces.asObservable())
.map { $0.map(NewSearchResultViewModel.place) }
.asDriver(onErrorJustReturn: [])

searchResultViewModel = Driver.merge(queryFetchResultViewModel, queryClearResultViewModel)

关于swift - 如何正确使用 switchLatest 在搜索结果和 tableview 的空状态之间切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44524991/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com