我想执行以下操作。我有一个事务列表,我希望通过为每个事务发出2个api请求(我正在使用retrofit2)来更新,然后将结果保存到数据库中(使用观察者)。经过一番搜索,我决定使用zip操作符来组合2个请求,但我遇到的问题是我无法识别整个过程何时完成更新UI。代码看起来像这样。
for (Transaction realmTransaction : allTransactions) {
Observable<Map<String, String>> obs1 = getObs1(realmTransaction);
Observable<Map<String, String>> obs2= getObs2(realmTransaction);
Observable.zip(obs1, obs2,
(map1, map2) -> {
Map<String, String> combined = new HashMap<>();
// do some processing and return a single map after
return combined;
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver(realmTransaction));
}
public Observer<Map<String, String>> getObserver(Transaction t){
return new Observer<Map<String, String>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Map<String, String> stringStringMap) {
// update database
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
}
}
我已经更新了realmTransaction对象字段的观察者。
我的问题是如何在for循环结束时收到通知?
我想在整个过程完成之后发送一个事件(可能使用EventBust)来启动其他方法。
感谢
我还有一个小问题是关于我在zip操作符中提供的函数,我如何指定该函数将在哪个线程上运行?我想使用计算线程,这就是为什么我把observeOn放两次,但我无法在任何地方找到答案
答案 0 :(得分:6)
每当你有for循环时,你应该考虑range
,fromArray
或fromIterable
。此外,您可能不需要完整的subscribe
,只需要doOnNext()
:
Observable.fromIterable(allTransactions)
.flatMap(realmTransaction -> {
Observable<Map<String, String>> obs1 = getObs1(realmTransaction);
Observable<Map<String, String>> obs2= getObs2(realmTransaction);
return Observable.zip(obs1, obs2, (map1, map2) -> {
Map<String, String> combined = new HashMap<>();
// do some processing and return a single map after
return combined;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(stringStringMap -> handle(stringStringMap, realmTransaction));
})
.ignoreElements()
.subscribe(() -> handleCompleted(), e -> handleError(e));
答案 1 :(得分:0)
由于每件事都是异步完成的,你可以在循环外创建一个局部变量,比如说count
并继续增加它getObserver
函数,然后检查计数是否等于{的长度{1}}。
关于你的第二个问题,我认为将使用订阅线程。您使用2 subscribeOn,将只使用最后一个。