Android 使用RxJava将本地数据与远程(或缓存)数据连接起来
这是一个有效的代码,但我有几个问题以及改进建议的请求。我是RxJava新手,我还没有完全了解如何将这些类型的观测值链接在一起 我有两个模型对象,Android 使用RxJava将本地数据与远程(或缓存)数据连接起来,android,rx-java,kotlin,rx-kotlin,Android,Rx Java,Kotlin,Rx Kotlin,这是一个有效的代码,但我有几个问题以及改进建议的请求。我是RxJava新手,我还没有完全了解如何将这些类型的观测值链接在一起 我有两个模型对象,ListItem和UserInfoListItems存在于本地数据库中,并且通过使用从ListItem提供的ID从服务器获取UserInfo UserInfoweb服务接受一个id数组,它将返回UserInfo对象列表 该代码的流程如下所示: 从数据库加载ListItems 使用从数据库中获取的ListItems,检查内存缓存,查看是否已获取特定List
ListItem
和UserInfo
ListItem
s存在于本地数据库中,并且通过使用从ListItem
提供的ID从服务器获取UserInfo
UserInfo
web服务接受一个id数组,它将返回UserInfo
对象列表
该代码的流程如下所示:
ListItem
sListItem
s,检查内存缓存,查看是否已获取特定ListItem的UserInfo
UserInfo
未缓存的任何项目,请从网络中获取它们UserInfo
对象放入缓存loadCachedUserInfo
)isUserList
,则只能为ListItem
获取UserInfo
对象
代码如下:
fun itemsInList(list : ATList, parentValue : String? = null, searchString : String? = null, limit : Int = defaultFetchLimit, sortOrder: SortDescriptor? = null) : Observable<List<ATListItem>> {
return Observable.create<List<ATListItem>> { subscriber ->
val listItems = listItemsInList(list, parentValue = parentValue, searchString = searchString, limit = limit, sortOrder = sortOrder)
subscriber.onNext(listItems)
subscriber.onCompleted()
}.flatMap { listItems ->
if ( list.isUserList ) {
return@flatMap loadCachedUserInfo(listItems, userIDIndex = list.userIDIndex!!)
}
return@flatMap Observable.just(listItems)
}.flatMap { listItems ->
if ( list.isUserList ) {
return@flatMap fetchUserInfoForListItems(listItems, list.userIDIndex!!, force = false)
}
return@flatMap Observable.just(listItems)
}
}
fun loadCachedUserInfo(listItems : List<ATListItem>, userIDIndex : Int) : Observable<List<ATListItem>> {
return Observable.create<List<ATListItem>> { subscriber ->
for ( listItem in listItems ) {
listItem.coreUserInfo = coreUserMap[listItem.valueForAttributeIndex(userIDIndex)?.toLowerCase()]
}
subscriber.onNext(listItems)
subscriber.onCompleted()
}
}
fun fetchUserInfoForListItems(listItems : List<ATListItem>, userIDIndex: Int, force: Boolean) : Observable<List<ATListItem>> {
val itemsToFetch = if ( force ) listItems else listItems.filter { it.coreUserInfo == null }
val ids = itemsToFetch.map { it.valueForAttributeIndex(userIDIndex) ?: "" }.filter { !it.isEmpty() }
val records = hashMapOf("records" to ids)
if ( itemsToFetch.count() == 0 ) {
return Observable.just(listItems)
}
return RuntimeDataController.dataService.fetchCoreUserInfo(recordsMap = records)
.map { json ->
val recordsArray = json.arrayValue("records")
for ( i in 0..recordsArray.length() - 1) {
val coreUserInfo = CoreUserInfo(recordsArray.getJSONObject(i))
coreUserMap[coreUserInfo.username.toLowerCase()] = coreUserInfo
coreUserMap[coreUserInfo.userID] = coreUserInfo
coreUserInfo.externalUserID?.let { coreUserMap[it] = coreUserInfo }
}
return@map listItems
}.flatMap { loadCachedUserInfo(listItems, userIDIndex = userIDIndex) }
}
doOnNext
。比如说,
.doOnNext { listItems ->
if ( list.isUserList ) {
cache(listItems, userIDIndex = list.userIDIndex!!)
}
}
fun cache(listItems : List<ATListItem>, userIDIndex : Int) {
// caching
}
可以这样写:
.flatMap { listItems ->
if ( list.isUserList )
loadCachedUserInfo(listItems, userIDIndex = list.userIDIndex!!)
else
Observable.just(listItems)
}
我没有测试代码。谢谢,doOnNext肯定是缺失的部分。我不再需要让我的缓存存储和查找成为一个可观察的方法,因为我可以在doOnNext中完成它们,这简化了一切。
.flatMap { listItems ->
if ( list.isUserList ) {
return@flatMap loadCachedUserInfo(listItems, userIDIndex = list.userIDIndex!!)
}
return@flatMap Observable.just(listItems)
}
.flatMap { listItems ->
if ( list.isUserList )
loadCachedUserInfo(listItems, userIDIndex = list.userIDIndex!!)
else
Observable.just(listItems)
}