在多个可观察量完成后执行某些操作

时间:2016-10-21 02:29:49

标签: java android rx-java reactive-programming rx-android

我在Android上使用RXJava并尝试将多个API调用链接在一起,并在两个API调用完成后执行某些操作。我的API调用看起来与提供的代码示例类似。基本上进行API调用,将每条记录写入onNext中的数据库,并在写完所有记录后,更新一些缓存。我想以异步方式触发这两个调用,然后在两个调用onCompleted后再执行其他操作。在RX中这样做的正确方法是什么?我不认为我需要拉链,因为我不需要将不同的流绑在一起。我想也许合并,但我的两个API调用返回一个不同类型的Observable。请告诉我。感谢。

    getUsers()
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .flatMap(Observable::from)
            .subscribe(new Subscriber<User>() {
                @Override
                public void onCompleted() {
                   updateUserCache();
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "Error loading users", e);
                }

                @Override
                public void onNext(User user) {
                    insertUserToDB(user);
                }
            });

    getLocations()
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .flatMap(Observable::from)
            .subscribe(new Subscriber<Location>() {
                @Override
                public void onCompleted() {
                   updateLocationCache();
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "Error loading Locations", e);
                }

                @Override
                public void onNext(Location location) {
                    insertLocationToDB(location);
                }
            });  

3 个答案:

答案 0 :(得分:0)

你正在思考。您应该使用zip运算符。

您的每个功能都应该拨打电话,写入数据库并执行您需要的所有操作。 Theat zip输出功能不同:调用它时,您可以确保所有Observable已成功完成 - &gt;只需完成您的反应流。

创建Observable的列表:

List<Observable<?>> observableList = new ArrayList<>();
observableList.add(
        getUsers()
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .flatMap(Observable::from)
            .insertUserToDB(user)
            .toList());

observableList.add(
        getLocations()
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .flatMap(Observable::from)
            .insertLocationToDB(location)
            .toList());

然后zip alll Observable&#39; s:

Observable.zip(observableList, new FuncN<Object, Observable<?>>() {
    @Override
    public Observable<?> call(Object... args) {
        return Observable.empty();
    }
}).subscribe(new Subscriber<Object>() {
    @Override
    public void onCompleted() {
        updateUserCache();
        updateLocationCache();
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(Object o) {

    }
});

这是伪代码,但我希望你理解这个想法。

答案 1 :(得分:0)

.zip()是正确的方法

您可能希望通过

使Retrofit返回Single而不是Observable

答案 2 :(得分:0)

如果有人需要它,这里是我根据R.Zagórski建议使用的代码:

$http