如何通过Rxjava / RxAndroid

时间:2017-04-05 11:28:40

标签: android rx-java rx-android

我是RxJava / RxAndroid的新手。我想使用RxJava / RxAndroid来实现以下情况:首先,从网络获取数据然后对数据进行一些检查,如果任何检查失败,只需在主线程中显示错误。

you can see flow chart here!

我尝试了一些RxJava操作,但未能找到一个很好的方法。 有人可以帮我吗?非常感谢!

我写了一些关于这种情况的测试代码(使用String作为数据),还有更简单的方法吗?

Observable.just(s)
            .flatMap(new Function<String, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(final String s) throws Exception {
            return Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> e) throws Exception {
                    if(s.length() < 3){
                        e.onError(new Throwable("len"));
                    }else{
                        e.onNext(s);
                        e.onComplete();
                    }
                }
            });
        }
    }).flatMap(new Function<String, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(final String s) throws Exception {
            return Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> e) throws Exception {
                    if(s.startsWith("a")){
                        e.onError(new Throwable("start"));
                    }else{
                        e.onNext(s);
                        e.onComplete();
                    }
                }
            });
        }
    }).subscribeOn(AndroidSchedulers.mainThread())
            .doOnError(new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception {
            System.out.println("get error: " + throwable.getMessage());
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            System.out.println(s);
        }
    });

2 个答案:

答案 0 :(得分:0)

虽然您可以使用flatMap()进行此操作,但此处不需要,您可以使用map()来检查数据并抛出错误:

 Observable.just(s)
            .map(new Function<String, String>() {
                     @Override
                     public String apply(@NonNull String s) throws Exception {
                         if (s.length() < 3) {
                             throw new Exception("len");
                         } else if (s.startsWith("a")) {
                             throw new Exception("start");
                         }
                         return s;
                     }
                 }
            )
            .subscribe(new Consumer<String>() {
                           @Override
                           public void accept(@NonNull String s) throws Exception {
                               System.out.println(s);
                           }
                       }, new Consumer<Throwable>() {
                           @Override
                           public void accept(@NonNull Throwable throwable) throws Exception {
                               System.out.println("get error: " + throwable.getMessage();
                           }
                       });

在这里检查发出的值,并根据您的检查简单地抛出相应的Exception。

无论如何,在您的示例中,您不需要自己创建Observable来发送错误/通过,您可以使用Observable.error()Observable.just()

  .flatMap(new Function<String, ObservableSource<?>>() {
                @Override
                public ObservableSource<?> apply(@NonNull String s) throws Exception {
                    if (s.length() < 3) {
                        return Observable.error(new Exception("len"));
                    } else if (s.startsWith("a")) {
                        return Observable.error(new Exception("start"));
                    } else {
                        return Observable.just(s);
                    }
                }
            })

此外,您未在订阅者处理onError()(但在doOnError()上),因此您将OnErrorNotImplementedException崩溃。

答案 1 :(得分:0)

你可以通过消除Observable.create()(你不应该使用它)来简化你的代码:

Observable.just(s)
    .doOnEach(s -> {
        Preconditions.checkArgument(s >= 3, "len");
        Preconditions.checkArgument(!s.startsWith("a"), "start");
    })
    .subscribe(...)

或者您可以使用doOnEach和Guava前提条件:

{{1}}