响应式编程和RxJava

7 阅读4分钟

一、响应式编程(总结来自编程导航www.codefather.cn/

1、什么是响应式编程

​ 响应式编程是一种编程范式,它专注于异步数据流变化传播

​ 响应式编程的核心是“数据流是第一等公民”,程序的逻辑建立在数据流的变化之上

2、核心概念

1)数据流

​ 响应式编程中,数据以流(Streams)的形式存在。流就像一条河一样,源源不断、由一个方向(例如从A系统到B系统再到C系统),它可以被过滤、观测或者跟另外的一条流合并成一个新的流。

比如用户的输入、网络请求、文件读取都可以被看作是数据流,可以很轻松的对流进行处理。

比如Java8中的Stream API,下列代码中将数组作为一个流,依次进行过滤、转换、汇聚

list.stream()
    .fiter()
    .map()
    .collet();

2)异步处理

​ 响应式编程是异步的,即不会阻塞线程,而是通过回调或者其他的机制在未来某一个时间节点处理结果。这提高了应用的响应性和性能。

3)传播变化

​ 当数据源发生变化时,响应式编程模型会自动将变化传播到依赖这些数据源的地方。这种传播是自动的,不需要显示的调用。

​ 例如:有一只股票涨了,所有订阅了这只股票的人,同时会收到APP的通知,而不用自己盯着看

总结:响应式编程更倾向于声明式编程风格,通过定义数据流的转换和组合来实现复杂的逻辑。比如:可以利用map、fiter等函数来实现数据的转换,而不是将一大堆的逻辑混杂在一个代码块里面。

二、RxJava

1、什么是RxJava

​ RxJava是一个基于事件驱动利用可观测序列来实现异步编程的类库,是响应式编程在Java语言上的体现。

2、核心概念

1)事件驱动

​ 事件可以是任何事情,如用户的点击操作、网络请求的结果、文件的读写。事件驱动的编程模型是通过事件触发行动。

​ 例如:前端开发中,用户点击按钮会进行弹窗,这就是“点击事件”触发了“弹窗行动”

btn.onClick(()->{
    //弹窗
    showModal();
})

​ 在RxJava中,事件可以被看作是数据流中的数据项,称为“事件流”或者“数据流”。每当一个事件发生,这个事件就会被推送给那些对它感兴趣的观察者。

2)可观测序列

​ 可观测序列是指一系列按照时间顺序发出的数据项,可以被观察和处理。可观测序列提供了一种将数据流和异步事件建模为一系列可以订阅和操作事件的方式。

​ 可以理解为在数据流的基础上封装了一层,多加了一点方法。

3、核心知识点

1)观察者模式

​ RxJava是基于观察者模式实现的,分别有观察者和被观察者两个角色,被观察者会实时传输数据流,观察者可以观测到这些数据流。

​ 基于传输和观察的过程,用户可以通过一些操作方法对数据进行转换或者处理。

​ 在RxJava中,观察者就是Oberserver,被观察者就是Flowable

Oberserver:适合处理相对较小的、可控的、不会迅速产生大量数据的场景。它不具备背压处理能力,也就是说,当数据产生速度超过数据消费速度时,可能会导致内存溢出或者其他问题

Flowable :是针对背压(反向压力)问题而设计的观测类型。背压问题出现于数据产生速度超过数据消费速度的场景。Flowable提供了多种针对背压策略来处理这种情况,确保系统在处理大量数据时仍然能够保持稳定。

​ 被观察者.subscribe(观测者),它们之间就建立了订阅关系,被观察者传输的数据或者发出的事件会被观察者观察到。

2)常用操作符

// 创建两个 Flowable 对象
Flowable<String> flowable1 = Flowable.just("A", "B", "C");
Flowable<String> flowable2 = Flowable.just("D", "E", "F");

// 使用 concat 操作符将两个 Flowable 合并
Flowable<String> flowable = Flowable.concat(flowable1, flowable2);

3)事件

onNext

​ 被观察者每发送一次数据,就会触发此事件

onError

​ 如果发送数据过程中产生意料之外的错误,那么被观察者就可以发送此事件

onComplete

​ 如果没有发生错误,那么被观察者在最后一次调用onNext之后发送此事件表示完成数据传输。

​ 对应的观察者得到这些事情之后,可以进行一系列的处理,例如:

flowable.observeOn(Schedulers.io())
    .doOnNext(item -> {
        System.out.println("来数据啦" + item.toString());
    })
    .doOnError(e -> {
        System.out.println("出错啦" + e.getMessage());
    })
    .doOnComplete(() -> {
        System.out.println("数据处理完啦");
    }).subscribe();