我有一种情况,在这种情况下,通过获取Item
对象,应该发生以下三种情况之一:
api1
和api2
加载数据,合并数据并返回Observable
。api2
加载数据,并将其与缓存中已有的数据合并到目前为止,这是我设法提出的最好的:
val cacheObservable = cache.fetchItem(itemId);
val api1Observable = api1.fetchItem(itemId);
val api2Observable = api2.fetchItem(itemId);
val resultObservable = cacheObservable!!.flatMap { item: Item? ->
if (item == null) {
/* Get the item data, and the full text separately, then combine them */
Observable.zip(api1Observable, api2Observable, { itemData, itemText ->
itemData.apply { text = itemText }
});
} else if (item.text.isNullOrEmpty()) {
/* Get the full text only, then add it to the already cached version */
cacheObservable.zipWith(api2Observable, { cachedItem, itemText -> cachedItem.apply { text = itemText; } });
} else {
/* if the data and the full text are provided, simply return */
Observable.just(item);
}
}.doOnNext { item -> cache.saveOrUpdateItem(item); }
return resultObservable;
到目前为止,这工作正常,但我一直在想,如果有更多的声明方式来实现相同的效果。欢迎提出建议。
答案 0 :(得分:0)
我不知道Kotlin语法,但这是一个可以翻译的Java示例。当项目不在缓存中时,需要cache.fetchItem(itemId)
才能完成而不是发出null
。
如果cacheFetch
发出项目,flatMap()
将确保该项目包含该文本,并在需要时从网络中获取该文本。
如果缓存中没有任何内容,fullFetch
将从网络获取它。
concatWith(fullFetch).take(1)
将确保只订阅fullFetch
。
如果项目已更新,则该项目仅保存到缓存中。
Observable<Item> cacheFetch = cache.fetchItem(itemId);
Observable<Item> fullFetch =
Observable
.zip(
api1.fetchItem(itemId),
api2.fetchItem(itemId),
(item, itemText) -> {
item.text = itemText;
return item;
})
.doOnNext(cache::saveOrUpdateItem);
Observable<Item> resultObservable =
cacheFetch
.flatMap(item -> {
if (item.text != null && !item.text.isEmpty()) {
return Observable.just(item);
}
return api2
.fetchItem(itemId)
.map(itemText -> {
item.text = itemText;
return item;
})
.doOnNext(cache::saveOrUpdateItem);
})
.concatWith(fullFetch)
.take(1);
}