RXJava原理_JavaScript的执行原理

大家好,又见面了,我是你们的朋友全栈君。

RXJava简单理解

首先,rxjava是什么?其实对于刚接触rxjava的宝宝而言,只需要掌握两点:

  • 观察者模式
  • 异步处理

观察上图,清楚生动刻画出了rxjava的观察者模式:

  • 开关(被观察者)作为的是事件的产生方(产生“on”和“off”这两个 Event),有它发起这起开关的事件。
  • 台灯(观察者)作为事件的处理方(处理的是“on”和“off”这两个事件),被动的执行on和off。
  • 在产生和完成中间,即在事件由产生方传递到处理方的过程中需要被加 工,过滤和装换等操作。

重点来了

既然rxjava是基于观察者来组建自己的逻辑的,那么我们就来创建观察者(Observer/Subscriber),被观察者(Observable),然后二者建立订阅的关系(就好像那根电线连接台灯和开关)实现台灯观察开关的具体模式,并且在传递过程中对事件进行处理(比如:降低电压)。 Tips: Observer是观察者的接口,Subscriber是实现该接口的抽象类,因此这两个类都可以作为观察者,只是Subscriber在Observer的基础上加入了一下拓展,加入了新的一些方法,所以一般更倾向于Subscriber作为观察者,下面我们就来敲一遍:

//创建被观察者(开关)
Observable switch = Observable.create(new Observable.onSubscribe<String>(){
@override
pubic void call(Subscriber<? super String> subscriber)
   {
   subscriber.onNext("on"); 
   subscriber.onNext("off");
   subscriber.onNext("on");
   subscribere.onCompleted();
   }
}); 

Jetbrains全家桶1年46,售后保障稳定

这是最原始的写法,创建了一个开关类(被观察者),产生了四个事件,开,关,开,结束,以上写法比较繁琐,下面两种比较偷懒的写法:

  • 模式一:
Observeable switch = Observable.just("on","off","on");
  • 模式二
String[] events = {
  
  "on","off","on"}; 
Observable switch = Observable.from(events);

其实以上两种写法都是对原生的写法进行了更加严密的封装,其实也是将被观察者(开关)的那些事件”on”,”off”,”on”进行包装成onNext(“on”)将这样的事件依次发送给观察者(台灯),最后再自己补上onComplete()事件。接下里我们创建观察者:

//创建观察者(原生模式)
Subscriber light = new Subscriber<String> {
   @override
   public void onCompleted(){
     Log.d(TAG,"has completed"); //事件处理完成时回调
  }
  @override
  public void onError(Throwable e){
  
  //事件出错回调 Log.e(TAG,"has error");
 }
 @override
 public void onNext(String s){
  
  //事件发生时回调
 Log.e(TAG,"handle this ..."+s);
 }

}

以上写法为原生的观察者写法,也是表较常见的写法,下面来个偷懒的写法:

  • 偷懒模式(非正式写法)
Action1 light = new Action1<String>{
@override
public void call(String s){
  Log.e(TAG,"handle this"+s);
}
}

为什么说它是非正式的写法,首先因为Action1是一个单纯的人畜无害的接口,和Observer没有任何关系,只不过Action1也可以当做观察者来使用,只不过它只能专门处理onNext)()事件,其中Action0,1,2…,0,1,2…代表call()方法能接收的参数个数,接下来我们把观察者和被观察者联系起来:

//订阅
switch.subscribe(light);//大功告成

但是刚开始的时候就是不理解为什么是被观察者订阅观察者,这是搞事情呢!到底谁观察着谁啊,别急有话好好说,询问了度娘之后才理解为什么这样写,按理说台灯观察开关从而开关,没毛病,应该是:light.subscribe(switch);才对啊,之所以开关订阅台灯是为了保证流失api的调用风格,那什么优势流式API的调用风格呢?

//这就是流式API调用风格
Oservable.just("on","off","on")//被观察者产生事件
          .filter(new Fun1(String,Boolean){
  
  //将事件进行过滤
                        @override
                        public Boolean call(String s){
                        return s! = null;
                        }
              })
           .subscribe(mSubscriber); //将过滤后的事件订阅给观察者是不是感觉看起来很流畅啊 

操作符(Operators)

 Observable.just("ON","OFF","ON")
                .map(new Func1<String, Object>() {
                    @Override
                    public Object call(String s) {
                        if(s.contentEquals("F")){
                            return "false";
                        }else {
                            return true;
                        }
                    }
                }).subscribe(new Action1<Object>() {
                    @Override
                    public void call(Object o) {
                        Log.e(TAG, "call: "+o.toString() ;
                    }
                });

利用map操作符将被观察者传递的行为进行过滤,将字符串中含有F返回false,不含的返回true,而对于map的参数中第一个为被观察者传递的对象第二个为转换过滤后的对象,通过上面的代码也可以清楚地表现出流式API的调用。 下面我们来看一下rxjava中如何异步处理: 在rxjava中有一个Scheduler —调度器,相当于线程控制器用来控制当前代码执行在哪个线程中,目前rxjava中内置了三种Scheduler:

  • Schedulers.immedate()表明直接运行在当前线程,不指定默认为该值;
  • Schedulers.newThread()表明每次执行将开启新的线程;
  • Schedulers.io() I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation()计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • AndroidSchedulers.mainThread()表明事件发生在主线程中。 有了以上几种线程调度器,就可以使用subscribeOn()和observerOn()来对线程进行控制了,subscribeOn():指定subscribe()发生的线程,即Observable.onSubscribe()被激活的线程(事件产生),observableOn():指定Subscriber执行的线程,即事件消费的线程;光说不练假把式:
Observable.just("1","2","3")
.subscribeOn(Schedulers.io())//指定subscribe()执行的线程为io线程
.observeOn(AndroidSchedulers.mainThread())//指定Subscriber回调执行线程为主线程
.map(new Func1<String, Integer>(){
@Override
public Integer call(String s) {
return Integer.valueOf(s);
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted: ");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: ");
}
@Override
public void onNext(Integer integer) {
tv_age.setText(integer+"");
Log.d(TAG, "onNext: "+integer);
}
});

以上代码编写在Androidstudio中,必须添加依赖库: compile ‘io.reactivex:rxjava:1.0.9’ compile ‘io.reactivex:rxandroid:1.1.0’

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/200735.html原文链接:https://javaforall.cn

相关文章

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个...
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:...
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程...