我尝试按此顺序实现在memory
,disk
,network
中查找项目的提供程序。如果我有正确的本地缓存,这样做的主要目的是避免网络调用。有一个问题,因为我对网络的调用使用过滤器来获取项目,我可以从本地查询中获得10个项目,但仍然需要转到网络,因为这些项目来自不同的网络调用,具有不同的查询参数。
现在我使用concat
和firstOrDefault
,检查列表是否为空或空。我已经实现了一种检查是否已经使用特定查询调用服务器的方法,并且在从磁盘读取时使用它来返回null。
我现在需要优化提供程序,以便:
(现在它停在第一个好的物品清单上)。
我尝试使用takeWhile
,使用一种方法,如果数据为空或为空,或者我没有为该查询调用服务器,则返回true。问题是如果对该项目的检查是假的,则takeWhile不会发出该项目,这意味着我不会获得最后一个好项目(这也是最好的项目)。
我能想到的最佳解决方案是在某个条件出现之前发出项目然后取消订阅的运算符。我找不到一个。
编辑:一些代码
解决方案1)使用firstOrDefault
:!DiskService.wasDownloaded()
时不会发出本地项,因为DiskService
会返回带有List<Item>
的空!DiskService.wasDownloaded()
public Observable<List<Item>> items() {
List<Observable> obs = new ArrayList<>();
Observable<List<Item>> memoryObs = Observable.defer(this::getMemoryItems);
Observable<List<Item>> diskObs = Observable.defer(this::getDiskItems);
Observable<List<Item>> networkObs = Observable.defer(this::getNetworkItems);
Observable<List<Item>> concat = Observable.concat(memoryObs, diskObs, networkObs;
return concat.firstOrDefault(new ArrayList<>(), this::canAccept);
}
private boolean canAccept(List<Item> data) {
return data != null && data.size() > 0;
}
//Method in DiskService
public boolean wasDownloaded(){
return true if the query was performed on the server, false otherwise.
}
解决方案2)使用takeWhile
。 takeWhile的问题是Observable不会发出没有检查其状态的项目,这意味着我不会获得最佳List。 hacky解决方案是将错误检查推迟到下一个项目,但这样即使没有必要,也会触发网络请求。使用此解决方案,我使用仅包含List的TrustedItemList
和一个告诉Observable是否可以信任非空项目列表的布尔值(memory
和{{始终为true) 1}},如果network
{/ p> wasDownloaded()
,则为true
disk
答案 0 :(得分:2)
我最终使用了自public object ValueToGet;
public delegate object GetValueDelegate(object _value);
public event GetValueDelegate GetEvent;
public Window1()
{
InitializeComponent();
GetEvent.Invoke(ValueToGet);
}
的自定义Observable.Operator
,只是在OperatorTakeWhile
方法subscriber.onNext(t)
之前调用subscriber.onCompleted()
进行了唯一更改。这样就会发出最后一项,即在布尔检查中返回false的项目。
onNext
我的public final class OperatorTakeWhileWithLast<T> implements Observable.Operator<T, T> {
private final Func2<? super T, ? super Integer, Boolean> predicate;
public OperatorTakeWhileWithLast(final Func1<? super T, Boolean> underlying) {
this((input, index) -> {
return underlying.call(input);
});
}
public OperatorTakeWhileWithLast(Func2<? super T, ? super Integer, Boolean> predicate) {
this.predicate = predicate;
}
@Override
public Subscriber<? super T> call(final Subscriber<? super T> subscriber) {
Subscriber<T> s = new Subscriber<T>(subscriber, false) {
private int counter = 0;
private boolean done = false;
@Override
public void onNext(T t) {
boolean isSelected;
try {
isSelected = predicate.call(t, counter++);
} catch (Throwable e) {
done = true;
Exceptions.throwIfFatal(e);
subscriber.onError(OnErrorThrowable.addValueAsLastCause(e, t));
unsubscribe();
return;
}
if (isSelected) {
subscriber.onNext(t);
} else {
done = true;
subscriber.onNext(t); //Just added this line
subscriber.onCompleted();
unsubscribe();
}
}
@Override
public void onCompleted() {
if (!done) {
subscriber.onCompleted();
}
}
@Override
public void onError(Throwable e) {
if (!done) {
subscriber.onError(e);
}
}
};
subscriber.add(s);
return s;
}
}
方法(解决方案2)现在结束于:
items()