RxHttp 介绍篇之多请求串行与并行(五)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liujingxing93/article/details/86651522

前言

现实开发中,一个页面很少只有一个请求的,一般都有多个请求,有的需要串行,有的需要并行,有n个接口,我们就要设置n个接口回调,如果是串行的话,还需要在当前接口成功或失败的地方,调用下个一个请求,一个接着一个,真的是要逼死强迫症患者,而且代码可读性非常的差,新人来了往往要看上半天,而且很容易出错,不好维护。

如果还未阅读之前的文章,请移步
RxHttp 一条链发送请求,新一代Http请求神器(一)
RxHttp 介绍篇之生命周期、公共参数相关配置(二)
RxHttp 介绍篇之Parser介绍(三)
RxHttp 介绍篇之Param介绍(四)
RxHttp 介绍篇之多请求串行与并行(五)
RxHttp 扩展篇之Parser扩展(六)
RxHttp 扩展篇之Param扩展(七)
RxHttp 扩展篇之注解处理器 Generated API(八)

我们来看看HttpSender是如何解决的(其实这一切都是RxJava的功劳)。

并行

现在很多页面是这样的,上面是Banner条,Banner条下面是数据列表(假设是学生列表),这样就涉及到两个接口,一个是获取Banner条数据,另一是获取学生列表数据,这两个接口没有任何关系,所以我们可以并行去实现

String bannerUrl = "http://www...."; //banner url
String studentUrl = "http://www....";  // 学生列表url
//Banner 的Observable对象
Observable<Banner> bannerObservable = RxHttp.get(bannerUrl)
        .fromSimpleParser(Banner.class);
        
//学生的Observable对象
Observable<List<Student>> studentObservable = RxHttp.get(studentUrl)
        .fromListParser(Student.class);  //使用ListParser解析集合对象
        
Disposable disposable = Observable
        .merge(bannerObservable, studentObservable) //这里使用RxJava组合符中的merge操作符,将两个被观察者合并为一个
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(o -> {
            //如果一切正常的话,这里会被回调2次,一次是Banner数据,一次Student列表
            if (o instanceof Banner) {
                //获取到banner数据
            } else if (o instanceof List) {
                //获取到学生列表数据
            }
        }, throwable -> {
            //出现异常
        }, () -> {
            //2个请求执行完毕,开始更新UI
        });

可以看到,我们首先通过HttpSender对象拿到Banner和Student的两个Observable对象,然后通过merge操作符,将两个Observable对象合并为一个,并订阅观察者,这样就能在onNext回调中拿到Banner和Student数据,并在onComplete回调中更新UI。

可是,这样就完了吗?熟悉RxJava的同学应该知道,RxJava在出现异常后并且回调到onError接口时,就会停止工作,那么如果Banner接口先出现异常,岂不是收不到Student信息了?很明确的回答,是的,那么,我们应该如何去处理呢,其实很简单,RxJava为我们提供了异常捕获操作符,如:onErrorResumeNext和onErrorReturn,不明白的,自己去了解一下,作用就是出现异常了,我们如何去补救它。在这,我们使用onErrorResumeNext操作符,代码如下

String bannerUrl = "http://www...."; //banner url
String studentUrl = "http://www....";  // 学生列表url
//Banner 的Observable对象
Observable<Banner> bannerObservable = RxHttp.get(bannerUrl)
        .fromSimpleParser(Banner.class)
        .onErrorResumeNext(Observable.empty()); //出现异常,发送一个空的Observable对象
        
//学生的Observable对象
Observable<List<Student>> studentObservable = RxHttp.get(studentUrl)
        .fromListParser(Student.class);  //使用ListParser解析集合对象
        
Disposable disposable = Observable
        .merge(bannerObservable, studentObservable) //将两个被观察者合并为一个
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(o -> {
            //如果一切正常的话,这里会被回调2次,一次是Banner数据,一次Student列表
            if (o instanceof Banner) {
                //获取到banner数据
            } else if (o instanceof List) {
                //获取到学生列表数据
            }
        }, throwable -> {
            //出现异常
        }, () -> {
            //2个请求执行完毕,开始更新UI
        });

上面我们只加了onErrorResumeNext(Observable.empty())这一行代码,Observable.empty()是一个不会发射任何事件的Observable对象。所以,这个时候如果Banner的Observable出现异常,就不会发射任何事件,Student 的Observable对象便可继续执行,只是在onNext回调中,就只能收到一次Student的回调(请求成功的话),并且随后执行onComplete回调更新UI,这样就能保证即使Banner接口出错了,我们依然可以正常现实学生列表数据。说的抽象一点就是保证A接口不影响B接口,但是B可以影响A接口,如果要保证A、B两个接口互不影响,分别对A、B接口处理异常即可,如果有3个、4个甚至更多的请求,可以使用Observable.mergeArray操作符。

串行

接下来,看看我们串行,假设我们有这样一个需求,需要在注册完成后立即去登录,这种情况下,就只能串行去实现,在这,我们列举两种方式,分别使用RxJava的mapflatMap这两个操作符去实现

map

String registerUrl = "http://www...."; //注册 url
String loginUrl = "http://www....";  // 登录url
Disposable disposable = RxHttp.postForm(registerUrl) //注册参数
        .add("userName", "zhangsan")
        .add("password", "123456")
        .fromSimpleParser(Register.class) //发送注册请求
        .map(register -> {    //这里使用map操作符,将Register对象转换为User对象
            //注册成功,拿到注册信息去登录,并返回User对象
            return RxHttp.get(loginUrl)
                    .add("userId", register.getUserId())
                    .add("password", register.getPassword())
                    //注意这里使用execute操作符
                    .execute(SimpleParser.get(User.class));
        })
        .observeOn(AndroidSchedulers.mainThread()) //主线程回调
        .subscribe(user -> {
            //注册并且登录成功,拿到用户信息
        }, throwable -> {
            //出现异常,注册失败或者登录失败
        });

flatMap

String registerUrl = "http://www...."; //注册 url
String loginUrl = "http://www....";  // 登录url
Disposable disposable = RxHttp.postForm(registerUrl) //注册参数
        .add("userName", "zhangsan")
        .add("password", "123456")
        .fromSimpleParser(Register.class)
        //这里使用flatMap操作符,将Register对象转换为Observable对象
        .flatMap((io.reactivex.functions.Function<Register, ObservableSource<User>>) register -> {
            //注册成功,拿到注册信息去登录,并返回User对象
            return RxHttp.get(loginUrl)
                    .add("userId", register.getUserId())
                    .add("password", register.getPassword())
                    //注意这里使用execute操作符
                    .fromSimpleParser(User.class);
        })
        .observeOn(AndroidSchedulers.mainThread()) //主线程回调
        .subscribe(user -> {
            //注册并且登录成功,拿到用户信息
        }, throwable -> {
            //出现异常,注册失败或者登录失败
        });

以上两种方式,只有两个地方不同,前者使用了map操作符,并调用的execute操作符返回一个User对象;后者使用flatMap操作符,并调用 from操作符返回一个Observable<User>对象,其实结果都是一样的,没有任何差异,个人推荐使用map操作符去实现,更直观,内部执行效率更高。

小结

看完你会发现,RxHttp真的做到了与RxJava的无缝连接,既可以返回一个Observable<T>对象,也可以返回一个具体的实体类对象,再结合RxJava强大的操作符,可以碰撞出非常多有意思的功能。

最后,一切功劳都要归功于RxJava的强大,感谢RxJava,向它致敬!!!!

猜你喜欢

转载自blog.csdn.net/liujingxing93/article/details/86651522