RxJava学习3--事件

有时有多个事件,但是我们需要汇集多个事件的结果返回。比如有个系统检测,分三个部分检测,分别是电气系统检测、安全系统检测、驱动系统检测。

检测结果封装:

public class CheckOutCome {
    public Boolean isSuccess = false;//检测是否成功
    public String Name;//项目名称

    public CheckOutCome(Boolean isSuccess, String name) {
        this.isSuccess = isSuccess;
        Name = name;
    }

下面是我们的屏幕:

    Observer ourScreen = new Observer<CheckOutCome>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Logger.log("检测开始", "");
            }

            @Override
            public void onNext(@NonNull CheckOutCome o) {
                Logger.log("ourScreen", "检测:" + o.Name+" 是否成功:"+o.isSuccess);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Logger.log("ourScreen onError", ""+e.getMessage());
            }

            @Override
            public void onComplete() {
                Logger.log("检测完成", "");
            }
        };

分别有三个检测模块:

Observable electricChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000);//检测需要3秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        e.onNext(new CheckOutCome(true,"电器系统检测"));
                        e.onComplete();
                    }
                }).start();
            }
        });

        Observable safeChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);//检测需要1秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        e.onNext(new CheckOutCome(true,"安全系统检测"));
                        e.onComplete();
                    }
                }).start();
            }
        });

        Observable driverChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);//检测需要2秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        e.onNext(new CheckOutCome(true,"驱动系统检测"));
                        e.onComplete();
                    }
                }).start();
            }
        });

1.事件合并

现在需求是,三个模块进行检测,检测完成返回结果显示在屏幕上,有一个检测出现问题,屏幕显示有问题,然后停止检测: 通过merge来合并事件,它的作用是遍历事件,如果有一个出现问题,然后异常。

 Observable observable = Observable.merge(electricChecker,safeChecker,driverChecker);
        observable.subscribe(ourScreen);

打印结果:

检测开始:
ourScreen:检测:安全系统检测 是否成功:true
ourScreen:检测:驱动系统检测 是否成功:true
ourScreen:检测:电器系统检测 是否成功:true
检测完成:

如果安全检测返回是这样:

 e.onNext(new CheckOutCome(true,"安全系统检测"));
                        e.onError(new Exception("安全系统检测出问题了"));

打印结果如下:

检测开始:
ourScreen:检测:安全系统检测 是否成功:true
ourScreen onError:安全系统检测出问题了

假如我想这样,汇总所有检测结果,所有结果都没问题了才返回检测成功,否则返回有问题。
将安全检测改为如下:

  e.onNext(new CheckOutCome(false,"安全系统检测"));
                        e.onComplete();

运行打印如下:

检测开始:
ourScreen:检测:安全系统检测 是否成功:false
ourScreen:检测:驱动系统检测 是否成功:true
ourScreen:检测:电器系统检测 是否成功:true
检测完成:

我想要的结果是,全部是ture返回检测成功,全部是false,返回检测失败。
这时可以通过zip来合并组合返回结果。

 Observable observable = Observable.zip(electricChecker, safeChecker, driverChecker, new Function3<CheckOutCome, CheckOutCome, CheckOutCome, CheckOutCome>() {
            @Override
            public CheckOutCome apply(@NonNull CheckOutCome o, @NonNull CheckOutCome o2, @NonNull CheckOutCome o3) throws Exception {
                if (o.isSuccess && o2.isSuccess && o3.isSuccess) {
                    return new CheckOutCome(true, "检测成功");
                }
                return  new CheckOutCome(false, "检测失败");
            }
        });
         observable.subscribe(ourScreen);

打印结果如下:

检测开始:
ourScreen:检测:检测失败 是否成功:false
检测完成:

这个可以应用与很多地方,比如一个页面获取数据需要去多个接口获取,如果我需要全部获取成功后才显示成功,如果有一个获取失败就显示异常,就可以这样处理。

值得注意的是,如果其中一个事件出现异常返回onError,会直接回调onError。如安全检测变为如下时:

  Observable safeChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(6000);//检测需要6秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        //e.onNext(new CheckOutCome(false, "安全系统检测"));使用onError就不要使用这个,会出问题的
                        e.onError(new Exception("安全系统检测出异常"));
                    }
                }).start();
            }
        });

打印结果如下:

检测开始:
ourScreen onError:

2.事件连接

假如现在想要这样:我先检测安全系统,再检测电气系统,再检测驱动系统,只要有一个出现有问题就停止检测。

其实可以通过concatmap将结果处理然后返回结果,但是真的需要实现这个需求,可以通过concat来实现,它是可以使事件迭代下去。

 Observable electricChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000);//检测需要3秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        e.onNext(new CheckOutCome(false, "电器系统检测"));
                        e.onComplete();
                    }
                }).start();
            }
        });

        Observable safeChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);//检测需要1秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        e.onNext(new CheckOutCome(false, "安全系统检测"));
                        e.onComplete();
                    }
                }).start();
            }
        });

        Observable driverChecker = Observable.create(new ObservableOnSubscribe<CheckOutCome>() {
            @Override
            public void subscribe(final @NonNull ObservableEmitter<CheckOutCome> e) throws Exception {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);//检测需要2秒
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        e.onNext(new CheckOutCome(false, "驱动系统检测"));
                        e.onComplete();
                    }
                }).start();
            }
        });


        Observable observable = Observable.concat(safeChecker,electricChecker,driverChecker);
        observable.subscribe(ourScreen);

打印如下:

检测开始:
ourScreen:检测:安全系统检测 是否成功:false
ourScreen:检测:电器系统检测 是否成功:false
ourScreen:检测:驱动系统检测 是否成功:false
检测完成:

那如何使第一个返回后进停止呢,可以通过以下代码获取第一个事件:


        Observable observable = Observable.concat(safeChecker,electricChecker,driverChecker).firstElement().toObservable();
        observable.subscribe(ourScreen);

打印结果:

检测开始:
ourScreen:检测:安全系统检测 是否成功:false
检测完成:

假如不是安全系统检测出问题了,那我们把这句注释:

  // e.onNext(new CheckOutCome(false, "安全系统检测"));
                        e.onComplete();

打印结果如下:

检测开始:
ourScreen:检测:电器系统检测 是否成功:false
检测完成:

可以看到下一个检测失败的信息将会返回。

这个可以应用在一些场景中:实现本地搜索,比如可以搜关键字,按照权重关键字先后在标题、用户名、地址、状态中匹配。匹配成功就返回不进行下面的匹配,就可以通过这个链式进行匹配了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值