ReactiveX
ReactiveX是一个库,用于使用可观察序列(observable sequence)组合异步和基于事件(event-based)的程序。
它扩展了观察者模式(observer pattern),以支持数据和/或事件的序列,并添加了操作符,允许您以声明的方式组合序列,同时抽象出底层线程、同步、线程安全、并发数据结构和非阻塞I/O等问题。
ReactiveX是观察者模式、迭代器模式(Iterator pattern)和函数式编程(functional programming)的最佳思想的组合.
可观察对象(Observables)是访问多个项的异步序列的理想方法,填补了这一空白
single items | multiple items | |
---|---|---|
synchronous | T getData() | Iterable<T> getData() |
asynchronous | Future<T> getData() | Observable<T> getData() |
它有时被称为 “ 函数响应式编程 | 功能活性编写的程序 | 函数式反应编程(functional reactive programming) ” ,但这是一个不准确的名称。ReactiveX可能是功能性的(functional),也可能是反应性的(reactive),但“函数响应式编程(functional reactive programming)”是另一回事。一个主要的不同点是,函数响应式编程对随时间不断变化的值进行操作(operates on values that change continuously over time),而ReactiveX对随时间变化的离散值进行操作(operates on discrete values that are emitted over time)。
为什么使用Observables:
ReactiveX可观察模型允许您使用与数组等数据项集合相同的简单可组合操作来处理异步事件流。它将您从错综复杂的回调网络中解放出来,从而使您的代码更具可读性,更不容易出现bug。
Observables是可组合的
像Java Futures这样的技术可以直接用于单个级别的异步执行,但是当它们嵌套在一起时,它们就开始增加非平凡的复杂性(non-trivial complexity)。
使用Futures来优化组合条件异步执行流是困难的(或者是不可能的,因为每个请求的延迟在运行时是不同的)。当然,这是可以做到的,但是很快就会变得复杂(因此很容易出错(error-prone)),或者过早地阻塞Future.get(),这就消除了异步执行的好处。
另一方面,ReactiveX Observables用于组合异步数据流和序列。
Observables是灵活的
ReactiveX可观测数据不仅支持单个标量值的发射(就像期货一样),还支持值序列甚至无限流的发射。Observable是一个抽象,可以用于这些用例中的任何一个。一个可观察对象具有与其镜像表亲Iterable相关联的所有灵活性和优雅性。
一个可观察对象(Observable)是异步/推“对偶”到同步Iterable的(asynchronous/push “dual” to the synchronous/pull Iterable)
event | Iterable (pull) | Observable (push) |
---|---|---|
retrieve data | T next() | onNext(T) |
discover error | throws Exception | onError(Exception) |
complete | !hasNext() | onCompleted() |
Observables不那么固执己见
ReactiveX并不偏向于某些特定的并发或异步源。Observables可以使用线程池、事件循环、非阻塞I/O、参与者(例如来自Akka)或任何适合您的需求、您的风格或您的专业知识的实现来实现。客户端代码将其与Observables的所有交互都视为异步的,无论您的底层实现是阻塞还是非阻塞,以及您选择如何实现它。
How is this Observable implemented?
public Observable<data> getData();
- 它是否与调用者在同一线程上同步工作?
- 它在不同的线程上异步工作吗?
- 它是否将工作分配给多个线程,这些线程可以以任何顺序将数据返回给调用者?
- 它是否使用一个参与者(或多个参与者)而不是线程池?
- 它是否使用带有事件循环的NIO来进行异步网络访问?
- 它是否使用事件循环将工作线程与回调线程分开?
从Observer的角度来看,这并不重要!
Callbacks有自己的问题
回调(Callbacks)通过不允许任何东西阻塞来解决Future.get()的过早阻塞问题。它们天生高效,因为它们在响应就绪时执行。
但是,与Futures一样,虽然回调在异步执行的单个级别上很容易使用,但是在嵌套组合中,回调会变得很笨拙。
ReactiveX是一个多语言实现
ReactiveX目前以多种语言实现,以尊重这些语言的习惯用法的方式实现,并且正在快速添加更多的语言。
反应性编程(Reactive Programming)
ReactiveX提供了一组操作符,您可以使用它们进行筛选、选择、转换、组合和组合(filter, select, transform, combine, and compose)Observables。这允许高效的执行和组合。
您可以将Observable类看作一个“push”,相当于Iterable,即“pull”。使用Iterable,消费者从生产者获取值,线程阻塞,直到这些值到达(arrive)。相反(By contrast),对于Observable,只要值可用,生产者就将值推送给消费者。这种方法(approach)更加灵活,因为值可以同步或异步到达(arrive)。
示例代码展示了如何将类似的高阶(high-order)函数应用于Iterable和Observable
Iterable | Observable |
---|---|
| |
Observable类型为Gang of Four的观察者模式(the Gang of Four’s Observer pattern)添加了两个缺失的语义,以匹配Iterable类型中可用的语义:
1.生产者向消费者发出没有更多可用数据的信号的能力(在这种情况下,Iterable上的foreach循环完成并正常返回;一个Observable调用它的观察者的onCompleted(observer’s onCompleted
)方法)
2.生产者向消费者发出错误已经发生的信号的能力(如果在迭代过程中发生错误,Iterable将抛出异常;一个Observable调用它的观察者的onError(observer’s onError
)方法)
通过这些添加,ReactiveX协调了Iterable和Observable类型。它们之间唯一的区别是数据流动的方向。这是非常重要的,因为现在你可以在一个Iterable上执行任何操作,你也可以在一个Observable上执行。
RxJava介绍:
RxJava是ReactiveX(反应性扩展)的Java VM实现:一个库,用于使用可观察序列组合异步和基于事件的程序。
RxJava是轻量级的
RxJava试图非常轻量级。它被实现为一个单独的JAR,它只关注可观察的抽象和相关的高阶函数。
RxJava是一种多语言实现
RxJava支持Java 6或更高版本以及基于jvm的语言,如Groovy、Clojure、JRuby、Kotlin和Scala。
RxJava的目标是提供比Java/Scala更多门语言的环境,并且它的设计考虑到了每种基于jvm的语言的习惯用法。(这是我们仍在努力的事情。)
RxJava库
以下外部库可以使用RxJava:
- Hystrix latency and fault tolerance bulkheading library.
- Camel RX provides an easy way to reuse any of the Apache Camel components, protocols, transports and data formats with the RxJava API
- rxjava-http-tail allows you to follow logs over HTTP, like
tail -f
- mod-rxvertx - Extension for VertX that provides support for Reactive Extensions (RX) using the RxJava library
- rxjava-jdbc - use RxJava with jdbc connections to stream ResultSets and do functional composition of statements
- rtree - immutable in-memory R-tree and R*-tree with RxJava api including backpressure
由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!
Hello , World !
感谢所有!