RXJava。确定for循环内的所有obervable何时完成

时间:2018-02-11 20:58:45

标签: android retrofit2 rx-java2

我想执行以下操作。我有一个事务列表,我希望通过为每个事务发出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放两次,但我无法在任何地方找到答案

2 个答案:

答案 0 :(得分:6)

每当你有for循环时,你应该考虑rangefromArrayfromIterable。此外,您可能不需要完整的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,将只使用最后一个。