美文网首页Android-RxJavaAndroid-Rxjava&retrofit&dagger
RxJava2.0文章四 - Zip操作符的用法

RxJava2.0文章四 - Zip操作符的用法

作者: 世道无情 | 来源:发表于2018-04-29 20:15 被阅读28次

    前言

    这一节主要讲解Zip操作符的用法

    1. Zip操作符


    Zip是通过一个方法将多个上游(多个水管、多个Observable)发射的事件结合到一起,然后发射这个组合事件,是严格按照顺序的,它只发射与发射数据量最少的上游(最少的水管、最少的Observable)一样多的数据。
    如下图所示:


    zip.png

    由上图可知:
    上游有两根水管,一根用于发射圆形事件,另一根用于发射三角形事件,通过Zip操作符,把圆形事件和三角形事件合并为一个矩形事件

    分解动作如下:


    zip分解图.png

    由分解图可知:

    • 组合过程是分别从两根水管取出各取出一个事件,且一个事件只能被使用一次,且严格按照事件发送顺序进行,也就是说不会出现圆形1、三角形B合并,也不会出现圆形2、三角形A合并;
    • 最终下游收到事件的数量 和上游 发送事件最少的那一根水管的事件数量相同。可以这样理解:因为是从每一根水管中取事件进行合并,最少的那根肯定先取完,这个时候,尽管其他水管尽管还有事件,但是没有其他事件与之进行合并,因此下游不会收到剩余的事件。
      示例代码如下:
        /**
         * zip操作符:
         *      组合过程是分别从两根水管中各取一个事件进行组合,并且一个事件只能被使用一次,且严格按照事件发送的顺序,
         *      也就是说不会出现1与B、2与A进行组合
         */
        public static void demo1(){
            Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
                @Override
                public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                    Log.e("TAG" , "emit 1") ;
                    emitter.onNext(1);
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit 2") ;
                    emitter.onNext(2);
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit 3") ;
                    emitter.onNext(3);
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit 4") ;
                    emitter.onNext(4);
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit complete1") ;
                    emitter.onComplete();
                }
            }).subscribeOn(Schedulers.io()) ;    // 让上游1(第一个水管)在子线程中执行
    
    
            Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    Log.e("TAG" , "emit A") ;
                    emitter.onNext("A");
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit B") ;
                    emitter.onNext("B");
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit C") ;
                    emitter.onNext("C");
                    Thread.sleep(1000);
    
                    Log.e("TAG" , "emit complete2") ;
                    emitter.onComplete();
    
                }
            }).subscribeOn(Schedulers.io()) ;      // 让上游2(第二个水管)在子线程中执行
    
    
            Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
                @Override
                public String apply(Integer integer, String s) throws Exception {
                    return integer + s;
                }
            }).subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.e("TAG" , "subscribe") ;
                }
    
                @Override
                public void onNext(String value) {
                    Log.e("TAG" , "next -> " + value) ;
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.e("TAG" , "error") ;
                }
    
                @Override
                public void onComplete() {
                    Log.e("TAG" , "complete") ;
                }
            });
        }
    

    2. 具体应用场景


    比如一个界面需要展示用户信息,而该用户信息必须从两个接口中获取,只有当这两个接口都调用成功后,才可以获取用户信息进行展示,这个时候就可以使用zip操作符;

    /**
         * zip具体示例实践
         */
        public static void pritice(){
            final Api api = RetrofitProvider.get().create(Api.class) ;
            
            // 创建上游1,在子线程中请求用户基本信息接口
            Observable<UserBaseInfoResponse> observable1 = 
                    api.getUserBaseInfo(new UserBaseInfoRequest())
                            .subscribeOn(Schedulers.io()) ;
            
            // 创建上游2:在子线程中请求用户额外信息接口
            Observable<UserExtraInfoResponse> observable2 = 
                    api.getUserExtraInfo(new UserExtraInfoRequest())
                            .subscribeOn(Schedulers.io()) ;
                    
            
            // 使用 zip操作符,进行组合事件  把 UserBaseInfoResponse、UserExtraInfoResponse组合成 UserInfo 
            Observable.zip(observable1, observable2, new BiFunction<UserBaseInfoResponse, UserExtraInfoResponse, UserInfo>() {
                @Override
                public UserInfo apply(UserBaseInfoResponse userBaseInfoResponse, UserExtraInfoResponse userExtraInfoResponse) throws Exception {
                    return new UserInfo(userBaseInfoResponse , userExtraInfoResponse);
                }
            }).observeOn(AndroidSchedulers.mainThread())   // 切换到主线程中,进行UI更新
                    
                    .subscribe(new Consumer<UserInfo>() {
                        @Override
                        public void accept(UserInfo userInfo) throws Exception {
                            // 在这两个接口请求成功后,然后切换到主线程中,进行UI更新
                        }
                    });
        }
    

    相关文章

      网友评论

        本文标题:RxJava2.0文章四 - Zip操作符的用法

        本文链接:https://www.haomeiwen.com/subject/cnumlftx.html