ReactiveX
ReactiveX是一個庫,用於使用可觀察序列(observable sequence)組合異步和基於事件(event-based)的程序。
它擴展了觀察者模式(observer pattern),以支持數據和/或事件的序列,並添加了操作符,允許您以聲明的方式組合序列,同時抽象出底層線程、同步、線程安全、併發數據結構和非阻塞I/O等問題。
可觀察對象(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
ble |
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 !
感謝所有!