官方文檔鏈接:http://reactivex.io/documentation/observable.html
1.前言
ReactiveX的概念是,一個觀察者訂閱一個被觀察者,然后觀察者響應(yīng)被觀察者產(chǎn)生/傳遞的每一個事件或事件隊列。這種模式有利于并發(fā)操作,當(dāng)?shù)却挥^察者產(chǎn)生/傳遞事件時,不需要阻塞線程,而是創(chuàng)建觀察者,隨時準(zhǔn)備響應(yīng)被觀察者將來時間做出的事情。
這節(jié)介紹什么是響應(yīng)模式,什么是觀察者和被觀察者(以及觀察者如何訂閱被觀察者)。以后將介紹如何使用各種被觀察者的操作符來連接被觀察者和改變他們行為。文檔附帶解釋用的圖表,下面示例反映圖表如何展示被觀察者和它的轉(zhuǎn)換:

2.被觀察者
可以理解為數(shù)據(jù)源,內(nèi)部封裝了一系列事件等待自己來調(diào)用,從而傳遞出去(產(chǎn)生事件)。
參考的文章:
- Single — 只產(chǎn)生一個事件的特定版本的被觀察者
- Rx Workshop: Introduction
- Introduction to Rx: IObservable
- Mastering observables (來自Couchbase的文檔)
- 2 minute introduction to Rx by Andre Staltz (“假設(shè)被觀察者是異步的不可變的數(shù)組”)
- Introducing the Observable by Jafar Husain (JavaScript視頻教程)
- Observable object (RxJS) by Dennis Stoyanov
- Turning a callback into an Rx Observable by @afterecho
3.異步處理
在許多軟件開發(fā)任務(wù)中,或多或少期望,編寫的指令按照書寫順序,依次執(zhí)行,逐步完成。但在ReactiveX中,許多指令可以并行執(zhí)行,并由觀察者按任意順序捕獲相應(yīng)結(jié)果。與方法調(diào)用相比,先定義被觀察者,然后用觀察者訂閱的模式來檢索和轉(zhuǎn)換數(shù)據(jù),隨時準(zhǔn)備著在某個時間點捕獲和響應(yīng)事件的發(fā)生。這種方式有一個好處,當(dāng)有一堆互不依賴的任務(wù)時,讓它們同時開始比等待上一個結(jié)束再開始下一個要好,因為所有任務(wù)完成消耗的時間只由耗時最長的任務(wù)決定。
有不少術(shù)語來描述這種異步編程和設(shè)計的模型,本文將采用:觀察者訂閱被觀察者。被觀察者通過調(diào)用觀察者的方法來傳遞事件和發(fā)送通知給自己的觀察者。在后面的文章中,有時會稱呼“觀察者”為“訂閱者”、“監(jiān)視者”、“響應(yīng)者”,這種模型通常也被稱為“響應(yīng)模式”。
4.創(chuàng)建觀察者
下面的例子將使用類似Groovy的偽代碼,因為ReactiveX在多種語言下都有實現(xiàn)。
普通方法調(diào)用——不是那種異步的、ReactiveX中典型的并行調(diào)用——流程就像這樣:
- 調(diào)用一個方法。
- 一個變量存儲那個方法返回的值。
- 用那個變量和它的新值做一些有意義的事。
// make the call, assign its return value to `returnVal`
returnVal = someMethod(itsParameters);
// do something useful with returnVal
在異步模型中,流程更像這樣:
- 定義一個方法,使用異步調(diào)用返回的值做一些有意義的事;這個方法是觀察者的一部分。
- 定義異步調(diào)用本身作為被觀察者。
- 通過觀察者訂閱被觀察者來關(guān)聯(lián)兩者(這一步引發(fā)被觀察者產(chǎn)生事件)。
- 繼續(xù)業(yè)務(wù)邏輯;每當(dāng)調(diào)用返回時,觀察者方法將開始對返回的值(被觀察者產(chǎn)生的事件)執(zhí)行操作。
// defines, but does not invoke, the Subscriber's onNext handler
// (in this example, the observer is very simple and has only an onNext handler)
def myOnNext = { it -> do something useful with it };
// defines, but does not invoke, the Observable
def myObservable = someObservable(itsParameters);
// subscribes the Subscriber to the Observable, and invokes the Observable
myObservable.subscribe(myOnNext);
// go on about my business
4.1.觀察的事件
若觀察者要通過subscribe()方法與被觀察者連接起來,需實現(xiàn)下面方法的一些子集:
onNext()每當(dāng)被觀察者產(chǎn)生一個事件,它將調(diào)用這個方法,并使用它產(chǎn)生的事件作為參數(shù)。
onError()被觀察者調(diào)用這個方法,表明它未能生成預(yù)期的數(shù)據(jù),或者遇到一些其它的錯誤,將不會接著調(diào)用onNext()或onCompleted()方法。onError()方法使用導(dǎo)致錯誤的指示,作為它的參數(shù)。
onCompleted()被觀察者調(diào)用onNext()方法之后,且沒有遇到任何問題,當(dāng)結(jié)束事件的產(chǎn)生時,它調(diào)用這個方法。
被觀察者可能調(diào)用onNext()方法零次或多次,之后可能調(diào)用onCompleted()或onError()方法中的一種,作為最終調(diào)用。這里約定一下,文章中調(diào)用onNext()方法稱為“產(chǎn)生事件”,而調(diào)用onCompleted()或onError()方法稱為“發(fā)送通知”。
def myOnNext = { item -> /* do something useful with item */ };
def myError = { throwable -> /* react sensibly to a failed call */ };
def myComplete = { /* clean up after the final response */ };
def myObservable = someMethod(itsParameters);
myObservable.subscribe(myOnNext, myError, myComplete);
// go on about my business
可以參考這篇文章 Introduction to Rx: IObserver
4.2.取消訂閱
有一些ReactiveX的實現(xiàn),定義了專門的觀察者,即訂閱者,實現(xiàn)了取消訂閱的方法。調(diào)用這個方法表明,訂閱者不再關(guān)心當(dāng)前訂閱的任何一個被觀察者。那些被觀察者(如果它們沒有被其它觀察者訂閱)之后可以選擇停止產(chǎn)生新的事件。取消訂閱的結(jié)果,將會回溯觀察者訂閱被觀察者時使用的操作鏈,并且將導(dǎo)致鏈中的每個節(jié)點停止傳遞事件(封裝在被觀察者對象中)。但這個過程不能保證立即發(fā)生,被觀察者有可能產(chǎn)生并嘗試傳遞事件,即使沒有觀察者再訂閱它,仍能持續(xù)一段時間。
4.3.命名規(guī)則
每種特定語言對ReactiveX的實現(xiàn),有許多共同點,但沒有規(guī)范的命名標(biāo)準(zhǔn)。因為它們都有自己的命名習(xí)慣,而且這些名字在不同的上下文中有不同的含義,或者不符合特定實現(xiàn)語言的習(xí)慣。
5.被觀察者類型
由被觀察者的類型,決定什么時候產(chǎn)生它自己的事件隊列。熱類型,在它被創(chuàng)建時會開始產(chǎn)生事件,之后任何觀察者再訂閱它,可能從隊列中間的某處開始捕獲。冷類型,則相反,等到有觀察者訂閱它才開始產(chǎn)生事件,所以能保證觀察者從開始捕獲整個隊列。
在ReactiveX的一些實現(xiàn)中,有一些被稱為可連接的被觀察者。這樣的被觀察者不會開始產(chǎn)生事件直到它的connect()方法被調(diào)用,不管是否有觀察者已經(jīng)訂閱它。
6.總結(jié)
理解被觀察者和觀察者,不過才剛剛接觸ReactiveX的概念。它們本身只能算是對標(biāo)準(zhǔn)觀察者模式(若有不清楚此模式的,后期會在設(shè)計模式文集中加以說明)輕微的擴展,以便適合處理一系列事件。
ReactiveX真正的核心,是通過操作符改變、組合和控制被觀察者產(chǎn)生的事件隊列。尤其允許將異步事件的隊列組合在一個聲明中,保留回調(diào)所有的優(yōu)點,但沒有回調(diào)嵌套處理的缺點。下一節(jié)將詳細(xì)給大家講解這些神奇的操作符。