ReactiveX是一个用观察者模式
开发异步
和基于事件编程
的库。
它扩展了观察者模式,支持流式的数据和事件,然后增加一些操作符可以用于灵活的处理流式数据与事件。其内置了很多不同类型的操作符,并且声明式的写法,让我们可以专注开发业务而无需考虑很多底层的线程,并发,非阻塞操作。
概念
什么是流式事件?
从事件维度上看,就是在不同时间依次发生的事件。比如说依次点击屏幕,如下可以看做流式的事件。stream of event
或者event flow
为什么使用观察者模式(Observable)?
观察者模型,让我们在处理异步事件流
时更加简单,就是提高效率。可以减少写很多的回调操作
单条数据(single items) | 多条数据(multi items) | |
---|---|---|
同步/synchronous | T getData() |
Iterable getData() |
异步/asynchronous | Future getData() |
Observable getData() |
如上图可以看出来,JDK本身没有提供对多条数据的异步支持。比如异步的返回,A,B,C三个东西,顺序不做要求,那么一般就要写三个Future。如果三个数据在同一个线程内处理,就是同步的。
Observable提供了一种理想化的方式来访问异步的流式数据(asynchronous sequences of multiple items)
Observables可以进行组合
Java的Future是一种直接的方式来处理单个异步的操作,但是如果嵌套使用Future的时候,在异步里面继续异步Future,代码就容易变得复杂不易维护。
组合多个Future进行异步化的条件执行下一步操作时,写法比较难优化。如果使用了Future.get可以更容易预测到结果,但是又过早的进入了阻塞。
ReactiveX Observables意在组合流式的异步数据。
Observables更加灵活
ReactiveX Observables不仅仅支持单个的数值,同时支持无限的数据流,无限数据流即永远都一直有新的数据出现,无法处理到最后。
上面提到了Observables是一种理想的方式处理异步的多个数据。其余同步的集合迭代器对比如下:
数据(event) | Iterable (pull) | Observable (push) |
---|---|---|
获取数据 | T next() |
onNext(T) |
发现错误 | throws Exception |
onError(Exception) |
完成处理 | !hasNext() |
onCompleted() |
相比于同步集合的pull数据,Observable是异步的push数据。
- 使用Iterable,当没有数据到达的时候会进入阻塞状态。
- 使用Observable,只要有数据可用的时候,就将数据推送给consumer,不管值是有还是没有,是同步还是异步。
Observable在经典的观察者模式中添加了两个新的语法,功能更强大灵活,并且也使得其写法与Iterable保持统一,让我们写Observable的时候就像在写Iterable:
- 当生产者数据被消耗完毕的时候,Observable调用Observer的
onCompleted
方法 - 当消费者在遇到错误或异常的时候,Observable调用Observer的
onError
方法
再看下Observable与Iterable的写法对比: 写法上没太大的变化,这里的Iterable可以看做Java 8中的Stream。
Observable的灵活还有其不关心其数据源的如何实现,不管是使用线程池,actors,event loop或者其它内容,在Observable看来都是异步的。
使用ReactiveX时,可以修改底层的Observable实现而不需要修改Observable的Consumer代码。
使用
ReactiveX更像是一种理念,常见的编程语言都有关于ReactiveX的实现。以Java的实现RxJava为例。
写一个简单的Hello World案例:
1 引入Maven。
io.reactivex.rxjava2
rxjava
2.2.12
2 编写Rxjava相关代码
public class RxHello {
public static void main(String[] args) {
// 1. 创建Observable
Flowable observable = Flowable
.just("hello", "world")
// 2. 使用Operator
.map(String::toUpperCase)
;
//3. 创建Observer
Consumer consumer = new Consumer() {
@Override
public void accept(String s) throws Exception {
System.out.println("收到数据:" + s);
}
};
// 4. 建立订阅关系
observable.subscribe(consumer);
}
}
上面代码看起来比较简单,实际上写的时候也确实比较简单,主要步骤就三步:加上操作符可以说是4步
1 创建Observable,ReactiveX提供了一些不同的Operator来创建,具体有没有实现要到对应的编程语言中看:
// 以下operator是可以创建
`Create`, `Defer`, `Empty`/`Never`/`Throw`, `From`, `Interval`, `Just`, `Range`, `Repeat`, `Start`, and `Timer
// 比如:
Observable.create();
Observable.defer();
Observable.just();
Observable.fromArray()
2 进行Observable的数据处理,内置了非常多的操作符。转换,过滤,统计,错误处理等等
常见的Map,FlatMap,Filter,Take,Skip等
3 创建Observer,即观察者或者消费者,用于接收Observable的数据
常见的类:FlowableSubscriber,Subscriber,Comsumer,主要是我们的代码逻辑。
4 建立Observable和Observer的关系。
最后
这里只是介绍了ReactiveX的概念,介绍关键异步流式数据,与观察者模式部分,提供了案例代码,了解ReactiveX的基本写法。
想要提要到ReactiveX的强大,还需要掌握其丰富的Operator操作符功能。
参考:
http://reactivex.io/intro.html
http://reactivex.io/documentation/observable.html
https://medium.com/@andrestaltz/2-minute-introduction-to-rx-24c8ca793877