我需要在大型数据集上实施搜索,这可能需要一些时间才能在移动设备上完成。所以我想在每个匹配结果可用时立即显示。
我需要从数据存储中获取所有可用数据,这些数据决定是从网络还是从设备获取数据。此致电是Observable
。一旦Observable的数据变得可用,我想循环它,应用搜索谓词并通知任何观察者发现任何匹配。
到目前为止,我的想法是每次搜索找到新匹配时使用PublishSubject
订阅并调用其onNext
函数。但是,我似乎无法让所需的行为发挥作用。
我正在使用MVVM + Android数据绑定,并希望在RecyclerView
中显示每个匹配的条目,因此对于观察视图模型接收的每个onNext
事件,我必须调用{{1在RecyclerView的适配器上。
notifyItemRangeInserted
-
class MySearch(val dataStore: MyDataStore) {
private val searchSubject = PublishSubject.create<List<MyDto>>()
fun findEntries(query: String): Observable<List<MyDto>> {
return searchSubject.doOnSubscribe {
// dataStore.fetchAll returns an Observable<List<MyDto>>
dataStore.fetchAll.doOnNext {
myDtos -> if (query.isNotBlank()) {
search(query, myDtos)
} else {
searchSubject.onNext(myDtos)
}
}.subscribe(searchSubject)
}
}
private fun(query: String, data: List<MyDto>) {
data.forEach {
if (it.matches(query)) {
// in real life I cache a few results and don't send each single item
searchSubject.onNext(listOf(it))
}
}
}
fun MyDto.matches(query: String): Boolean // stub
}
我对上述代码的问题是,对于空查询class MyViewModel(val mySearch: MySearch, val viewNotifications: Observer<Pair<Int, Int>>): BaseObservable() {
var displayItems: List<MyItemViewModel> = listOf()
fun loadData(query: String): Subscription {
return mySearch.findEntries(query)
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(this::onSearchResult)
.doOnCompleted(viewNotifications::onCompleted)
.doOnError(viewNotifications::onError)
.subscribe()
}
private fun onSearchResult(List<MyDto> data) {
val lastIndex = displayItems.lastIndex
displayItems = data.map { createItem(it) }
notifyChange()
viewNotifications.onNext(Pair(lastIndex, data.count()))
}
private fun createItem(dto: MyDto): MyItemViewModel // stub
}
连续3次调用,当查询不为空时MyViewModel::onSearchResult
根本不被调用。
我怀疑问题出在我嵌套MyViewModel::onSearchResult
中的Observables的方式或我订阅错误/从错误的线程获取数据的方式。
有没有人对此有所了解?