java - 如何在 RX java 链中使用 "if-else"?

标签 java android rx-java rx-android rx-java2

我是 RXJava/RXAndroid 的新手。我想实现这种情况:根据 RXJava 中的某些条件选择不同的方式。 例如,首先,我从网络中获取用户信息,如果这是 VIP 用户,我将继续从网络中获取更多信息,或者只在主线程中显示一些信息(打破链条。)这里的流程图:/image/0hztR.png

我对此做了一些搜索,只发现“switchIfEmpty”可能有帮助。 我写了下面的代码:

getUserFromNetwork("userId")
                .flatMap(new Function<User, ObservableSource<User>>() {
                    @Override
                    public ObservableSource<User> apply(User user) throws Exception {
                        if(!user.isVip){
                            //show user info on MainThread!
                            return Observable.empty();
                        }else{
                            return getVipUserFromNetwork("userId");
                        }
                    }
                }).switchIfEmpty(new ObservableSource<User>() {
                    @Override
                    public void subscribe(Observer<? super User> observer) {
                        //show user info in main thread
                        //just break the chain for normal user
                        observer.onComplete();
                    }
                }).doOnNext(new Consumer<User>() {
                    @Override
                    public void accept(User user) throws Exception {
                        //show vip user info in main thread
                    }
                }).subscribe();

有没有更简单的方法来实现这个?

谢谢!

最佳答案

flatMap() 是一个不错的选择,您可以用它拆分流,但最后流合并在一起(每个拆分的可观察流的所有排放都流向主流)。 在您的代码中,switchIfEmpty() 是多余的,因为这正是 Observable.empty() 所做的(立即调用 onCompleted()),如果您希望显示在主线程上发生,您当然还需要观察者开启,但无论如何,我认为在流中间处理它不是一个好习惯。

我认为在您的情况下,您可以在单个处理程序中处理(响应)用户发射,因为它非常相似,只需检查它是否是 VIP 并相应地显示它。 所以它应该看起来像这样:

getUserFromNetwork("userId")
            .flatMap(new Function<User, ObservableSource<User>>() {
                @Override
                public ObservableSource<User> apply(User user) throws Exception {
                    if (!user.isVip) {
                        return Observable.just(user);
                    } else {
                        return getVipUserFromNetwork("userId");
                    }
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(user -> {
                if (user.isVip){
                    //display vip user
                }else{
                    //display regular user
                }
            });

在这种方法中,您有一个单一的流,在流的中间没有“副作用”。

如果你处理的是完全不同的(这不是这种情况),那么你可以将流拆分为 2 个独立的流并对每个流做出不同的 react ,这可以通过多播你的 getUserFromNetwork() 来完成 Observable,并从这个 Observable 创建 2 个不同的 Observable,一个将继续,例如 getVipUserFromNetwork(),一个不',并且每个都可以有不同的订阅者逻辑。 (你可以阅读 here 我关于多播的回答)

关于java - 如何在 RX java 链中使用 "if-else"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43382603/

相关文章:

java - getHibernateTemplate().find() 中的 SQL 注入(inject)

java - 我不应该将哪些 java android 文件上传到我的 SVN 服务器?

java - Spring 的 "@Validated"不适用于 Liberty 和注入(inject)

android - 在底部选项卡导航中重新附加到其 fragment 容器时,嵌套 fragment 的状态会丢失

java - RxJava : Reduce not working as expected

java - 为什么我无法定义数组?

java - 无法一次从节点 "History"获取一个 key

android - 渲染立方体

rx-java - 如果第二个可观察值立即失败,ReactiveX concat 不会从第一个可观察值生成 onNext

rxjs - 如果相同的发射发生在 x 毫秒前,则阻止发射