简体   繁体   中英

How to implement check-chain by Rxjava/RxAndroid

i am a newer on RxJava/RxAndroid. I want to use RxJava/RxAndroid to implement the following case: First, get data from network then do some checks on the data, if any of check fails, just show error in Main Thread.

you can see flow chart here!

I try some RxJava operations but fail to find a nice way to do so. Can someone help me on this? Many thanks!

And I write some test code about this case (using String as data), is there any more simple way?

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);
        }
    });

While you can do it with flatMap() it is not needed here, you can simply use map() for checking the data and throwing errors:

 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();
                           }
                       });

here you checking the value emitted and simply throw the appropriate Exception according to your checks.


Anyhow, in your example, you don't need to create by yourself an Observable for emitting errors/passing thru, you can use Observable.error() and 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);
                    }
                }
            })

moreover, your'e not handling onError() at your subscriber (but on doOnError() ) so you'll crash with OnErrorNotImplementedException .

You can simplify your code a bit by eliminating Observable.create() (which you should not be using anyway):

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

Or you can use doOnEach and Guava Preconditions:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM