Rxjava到底是什么
一個詞:異步
一個可以在java VM上使用可觀測的序列來組成異步的、基本事件的程序庫
一個實現異步操作的庫
RXJava優缺點
簡潔
隨著程序的邏輯變得越來越復雜,它依然能夠保持簡潔。
API介紹和原理解析
1.概念:擴展的觀察者模式
RXjava的異步實現,是通過一種擴展的觀察者模式
觀察者模式
觀察者模式的面向需求是:對象A(觀察者)對對象B(被觀察者)的某種變化,高度敏感,需要在B變化的一瞬間做出反應。
觀察者模式采用注冊(register)或者成為訂閱(subscrible)的方式,告訴被觀察者,我需要你的某某狀態,你要在它變化的時候告訴我。
Android開發中典型的例子就是view的點擊監聽器OnClickLinstener()。對設置onClickListener來說,view是被觀察者,OnClickListener是觀察者,二者通過setOnClickListener完成訂閱關系。訂閱完成之后,用戶點擊view的瞬間,Android Framework就會將點擊事件交給已經注冊的onClickListener采取這樣被動的觀察方式,既省去了反復檢索狀態的資源消耗,也能夠得到最高的反饋速度。
OnClickListener 的模式大致如下圖:
[圖片上傳失敗...(image-2917dc-1512961567324)]
如圖所示,通過setOnClickListener方法Button持有OnClickListener的引用,當用戶點擊Button,自動調用OnclickListener里的onClick方法。
把圖片抽象出來 Button->被觀察者 OnClickListener->觀察者 setOnClickListener->訂閱 onClick->事件。就由專用的觀察者模式(例如只用于監聽控件點擊)轉變成了通用的觀察者模式。
[圖片上傳失敗...(image-ed19bb-1512961567324)]
而 RxJava 作為一個工具庫,使用的就是通用形式的觀察者模式。
RXJava的觀察者模式
RXjava有4個感念:
- Observable 被觀察者
- Observer 觀察者
- subscribe 訂閱
- 事件
Observable和Observer通過Subscribe方法實現訂閱,從而Observable可以在需要的時候發出事件通知Observer。
與傳統的觀察者模式不同,除了普通事件onNext() (相當于onClick/OnEvent),還定義兩個特殊的事件onCompleted(),onError | completed 完成 完整的|
- onComplete() 事件隊列完結。RXJava不僅把每個事件單獨處理,還會把他們看成一個隊列RXJava規定,如果沒有新的onNext()方法發出時,必須出發onCompleted方法作為完成標志。
- onError() 事件隊列異常,在事件處理過程中出現異常,會觸發onError(),并且整個事件終止,不允許在有事件發出。
- 在一個正確運行事件序列中,onCompleted,onError有且只有一個會被調用,而且是事件中最后一個方法,兩個方法是互斥的。即在隊列中調用了其中一個,就不應該再調用另一個。
RxJava 的觀察者模式大致如下圖:
[圖片上傳失敗...(image-f381dc-1512961567324)]
基本實現
基于以上的概念, RxJava 的基本實現主要有三點:
創建Observer 觀察者
決定著事件觸發將有怎樣的行為
Observer<String> observer = new Observer<String>() {
@Override
public void onNext(String s) {
Log.d(tag, "Item: " + s);
}
@Override
public void onCompleted() {
Log.d(tag, "Completed!");
}
@Override
public void onError(Throwable e) {
Log.d(tag, "Error!");
}
};
除了 Observer 接口之外,RxJava 還內置了一個實現了 Observer 的抽象類:Subscriber。 Subscriber 對 Observer 接口進行了一些擴展,但他們的基本使用方式是完全一樣的:
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onNext(String s) {
Log.d(tag, "Item: " + s);
}
@Override
public void onCompleted() {
Log.d(tag, "Completed!");
}
@Override
public void onError(Throwable e) {
Log.d(tag, "Error!");
}
};
不僅基本使用方式一樣,實質上,在RxJava的subscribe過程中,Observer也總是會先被轉換成Subscriber在使用。所以使用基本功能,選擇Observer或者subscriber都是一樣的。他們的區別有兩點。
- onStart() 這是subscriber新增方法,他會在subscribe剛開始,但是事件還沒有發送之前被調用,可以用于做一些準備工作,例如數據清零或者重置,這是一個可選的方法。默認實現為空。但是如果對工作線程有要求的話(例如彈出一個對話框,需要在Ui線程執行),就不能使用onStart(),因為他總是調用在subscribe所發生的線程調用,而不能指定線程。如果指定線程來做準備工作,可以使用doOnSubscribe()方法。
- unSubscribe 這是Subscriber所實現的另一個接口Subscription()方法,用于取消訂閱,在這個方法調用后Subscriber將不接受任何事件。一般在調用之前先使用isUnSubscribed先判斷一下狀態,unSubscribe()這個方法很重要,因為在subscribe之后,Observable會持有Subscriber的引用,這個引用如果不能及時被釋放,將有內存泄露的風險。所以要保持良好的原則,要在不再使用的時候盡快在合適的地方(例如 onPause() onStop() 等方法中)調用 unsubscribe() 來解除引用關系,以避免內存泄露的發生。
創建Observeable
Observable是被觀察者,決定在什么時候被觸發,和觸發什么事件。
RXJava使用create()方法來創建一個Observable,并為他設置事件觸發規則。
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("Hi");
subscriber.onNext("Aloha");
subscriber.onCompleted();
}
});
這里傳入OnSubScribe對象作為參數,OnSubscribe會被存入染回的Observable對象中,相當于一個計劃表,當OnSubscribeObservable被訂閱時,OnSubscriable的call方法會被自動調用,事件序列會按照設定依次調用onNext方法和OnCompleted方法,這樣,由被觀察者調用了觀察者的回調方法,就實現了被觀察者向觀察者的事件傳遞,即觀察者模式。
create方法是RXJava中最基本的創造事件序列的方法。RXJava還提供了一些方法用來快捷創建事件隊列,例如:
- just<T...> 將傳入的參數依次發送出來。
Observable observable = Observable.just("Hello", "Hi", "Aloha");
// 將會依次調用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
- from(T...) / from(Iterable<? extends T> 將傳入的數組 或者 Iterable 拆分成具體對象后,依次發送出來。
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
// 將會依次調用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
上面 just(T...) 的例子和 from(T[]) 的例子,都和之前的 create(OnSubscribe) 的例子是等價的。
Subcsribe訂閱
創建了Observable和Observe之后,用subscribe方法將他們鏈接起來,整條鏈子就可以工作了。
observable.subscribe(observer);
// 或者:
observable.subscribe(subscriber);
Observable.subscribe(Subscriber) 的內部實現是這樣的(僅核心代碼):
// 注意:這不是 subscribe() 的源碼,而是將源碼中與性能、兼容性、擴展性有關的代碼剔除后的核心代碼。
// 如果需要看源碼,可以去 RxJava 的 GitHub 倉庫下載。
public Subscription subscribe(Subscriber subscriber) {
subscriber.onStart();
onSubscribe.call(subscriber);
return subscriber;
}
subscribe做了三件事
- 調用的Subscriber的onStart方法,可選的準備方法。
- 調用observable中的Call方法。在這里,事件發送的邏輯開始運行。在RXjava中Observable不是在創建時候就立即發送事件,而是在他訂閱的時候,即放subscribe執行的時候。
- 將傳入的subscribe作為Subscription返回,為了方便unSubscribe。
整個關系如下
[圖片上傳失敗...(image-17e6e0-1512961567324
或者
[圖片上傳失敗...(image-7845b8-1512961567324)]
除了subscribe(Observer) 或者 subscribe(subscriable),subscribe還支持不完整定義的回調,RXJava會自動創建出Subscriber
Action1<String> onNextAction = new Action1<String>() {
// onNext()
@Override
public void call(String s) {
Log.d(tag, s);
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
// onError()
@Override
public void call(Throwable throwable) {
// Error handling
}
};
Action0 onCompletedAction = new Action0() {
// onCompleted()
@Override
public void call() {
Log.d(tag, "completed");
}
};
// 自動創建 Subscriber ,并使用 onNextAction 來定義 onNext()
observable.subscribe(onNextAction);
// 自動創建 Subscriber ,并使用 onNextAction 和 onErrorAction 來定義 onNext() 和 onError()
observable.subscribe(onNextAction, onErrorAction);
// 自動創建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 來定義 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
Action0是RxJava中的一個接口,它只有一個方法Call,這個方法是一個無參無返回值的方法,由于onCompleted也是無參無返回值的,因此action可以當成一個包裝對象,將onCompleted內容打包起來將自己作為一個參數傳入subscribe中,以實現不完整定義的回調。也可以看做將onCompleted方法傳遞進了subscribe,相當于某些語言中的閉包。
Action1也是一個接口,他同樣也只有一個方法Call(T param),這個方法無返回值,但是有一個參數,與Action0同理,由于onNext onError也是只有一個單參數,且沒有返回值,因此Action1可以將OnNext(obj)和onError(error)打包起來傳入subscribe中,以實現不完整定義的回調,事實上,雖然 Action0 和 Action1 在 API 中使用最廣泛,但 RxJava 是提供了多個 ActionX 形式的接口 (例如 Action2, Action3) 的,它們可以被用以包裝不同的無返回值的方法。
場景事例
打印字符數組
將字符串數組 names 中的所有字符串依次打印出來:
String[] names = {"馮星","曹操","趙云","馬超"};
rx.Observable.from(names).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG, "call: " +s);
}
});
由 id 取得圖片并顯示
由指定的一個 drawable 文件 id drawableRes 取得圖片,并顯示在 ImageView 中,并在出現異常的時候打印 Toast 報錯:
Observable<Drawable> observable = Observable.create(new Observable.OnSubscribe<Drawable>() {
@Override
public void call(Subscriber<? super Drawable> subscriber) {
subscriber.onNext(getResources().getDrawable(R.mipmap.water));
subscriber.onCompleted();
}
});
observable.subscribe(new Subscriber<Drawable>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(Drawable drawable) {
iv_demo.setImageDrawable(drawable);
}
});
正如上面兩個例子這樣,創建出 Observable 和 Subscriber ,再用 subscribe() 將它們串起來,一次 RxJava 的基本使用就完成了。非常簡單。
[圖片上傳失敗...(image-9074f5-1512961567324)]
在RXjava默認規則里,事件的發出和消費都在同一個線程里。也就是說上面是一個同步的觀察者模式。
而觀察者模式本身的目的在于 后臺處理,前臺調用 的異步機制。因此異步對于 RxJava 是至關重要的。而要實現異步,則需要用到 RxJava 的另一個概念: Scheduler 。
線程控制 -- Scheduler |si gan diu le| 調度
在不指定線程的情況下,RXjava遵循的是線程不變得原則,
即,在那個線程調用Subscribe,就在哪個線程生產事件;在哪個線程生產的事件,就在那個線程消費事件,
如果需要切換線程,就需要用到 Scheduler (調度器)。
Schedule的API
在RXjava中,schedule--調度器,相當于線程控制器,RXJava通過它來指定每一段代碼應該運行哪一個線程。
- Schedulers.immediate() 運行在當前線程,相當于不指定線程。這是默認的schedule。 |ai mi dei rui te| 立即的 立刻的
- Schedulers.newThread() 總是啟用新線程。并在新線程執行操作。
- Schedulers.io() io操作(讀寫文件,讀寫數據庫,網絡信息交互等)所使用的schedule。行為模式和newThread差不多。區別在于Io的內部實現是用一個無數量上線的線程池,可以重復利用閑置的線程。因此多數情況下,io要比newThread更有效。不要把計算工作放在 io() 中,可以避免創建不必要的線程。
- Schedulers.computation() 計算時使用的schedule。這個計算指的是CPU密集型計算,即不會被I/O等操作限制性能的操作,例如圖形計算。這個Scheduler使用固定的線程池,大小為CPU的核數,不要把I/O放在computation中,否則I/O操作的等待時間會浪費CPU。
- AndroidSchedules.mainThread() Android專用線程,他指定的操作將在主線程中運行。
subscribeOn() 指定subscribe()所發生的線程,即Observable.OnSubscribe()被激活時所發生的線程?;蛘呓凶鍪录a生的線程。
ObserveOn()指定subscriber所發生的線程或者叫做事件消費的線程。
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) // 指定 subscribe() 發生在 IO 線程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回調發生在主線程
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer number) {
Log.d(tag, "number:" + number);
}
});
由于subscribeOn(Schedulers.io())的指定,被創建的事件1,2,3,4,將會在在Io線程發出。
由于observeOn(AndroidSchedulers.mainThread())的指定,因此subscriber的數字打印將發生在主線程。
事實上,這種在 subscribe() 之前寫上兩句 subscribeOn(Scheduler.io()) 和 observeOn(AndroidSchedulers.mainThread()) 的使用方式非常常見,它適用于多數的 『后臺線程取數據,主線程顯示』的程序策略。
Schedule的原理
下面呢
變換
RxJava 提供了對事件序列進行變換的支持,這是它的核心功能之一
所謂變換,就是將事件序列中的對象或者整個序列進行加工處理,轉換成不同的事件或者事件序列。
API
map()
Observable.just(R.mipmap.water)
.map(new Func1<Integer, Bitmap>() {
@Override
public Bitmap call(Integer s) {
return BitmapFactory.decodeResource(getResources(),s);
}
})
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) {
iv_demo.setImageBitmap(bitmap);
}
});
Func1和Action1非常相似。也是RXJava中的一個接口。用于包裝有一個參數的方法。Func1和Action1的區別在于,Func1是由返回值得。另外,和 ActionX 一樣, FuncX 也有多個,用于不同參數個數的方法。FuncX 和 ActionX 的區別在 FuncX 包裝的是有返回值的方法。
map()方法將參數中的string對象轉換成BitMap對象后返回,經過map方法后,事件的參數也隨之變成的bitmap
- map():事件對象的直接變換,是最常見的轉換。
[圖片上傳失敗...(image-2a65d2-1512961567324)]
- flatMap() 這是一個很有用但非常難理解的變換,因此我決定花多些篇幅來介紹它。 首先假設這么一種需求:假設有一個數據結構『學生』,現在需要打印出一組學生的名字。實現方式很簡單:
Observable.from(students)
.map(new Func1<Student, String>() {
@Override
public String call(Student student) {
return student.getName();
}
})
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG, "call: "+s);
}
});
很簡單。那么再假設:如果要打印出每個學生所需要修的所有課程的名稱呢?(需求的區別在于,每個學生只有一個名字,但卻有多個課程。)首先可以這樣實現:
Observable.from(students)
.subscribe(new Action1<Student>() {
@Override
public void call(Student student) {
List<Course> courses = student.getCourses();
for(Course course : courses){
Log.d(TAG, "onNext: "+ course.getName() + " Student : " +student.getName());
}
}
});
依然很簡單。那么如果我不想在 Subscriber 中使用 for 循環,而是希望 Subscriber 中直接傳入單個的 Course 對象呢(這對于代碼復用很重要)?用 map() 顯然是不行的,因為 map() 是一對一的轉化,而我現在的要求是一對多的轉化。那怎么才能把一個 Student 轉化成多個 Course 呢? 這時候就需要flatMap了
Observable.from(students)
.flatMap(new Func1<Student, Observable<Course>>() {
@Override
public Observable<Course> call(Student student) {
return Observable.from(student.getCourses());
}
}).subscribe(new Action1<Course>() {
@Override
public void call(Course course) {
Log.d(TAG, "call: " + course.getName());
}
});
flatMap和map有個相同點:也是把傳入的參數轉化之后返回另一個對象。但是需要注意的是flatMap返回的對象是Observable對象。并且這個Observable對象不是直接發送到了Subscriber的回調方法中。
flatMap的原理是這樣的
- 使用傳入的事件對象創建一個Observable對象。
- 并不發送這個Observable對象,而是將它激活,于是它開始發送事件。
- 每一個創建出來的Observable發送的事件,都匯入同一個Observable對象,而這個observable對象負責將這些事件傳入Subscriber對象。
這三個步驟吧事件分成了兩級,通過一組新創建的Observable將初始的對象鋪平,之后通過統一路徑分發下去,而這個『鋪平』就是 flatMap() 所謂的 flat
flatMap()示意圖
[圖片上傳失敗...(image-a79136-1512961567324)]
擴展
由于可以在嵌套的 Observable 中添加異步代碼, flatMap() 也常用于嵌套的異步操作,例如嵌套的網絡請求。示例代碼(Retrofit + RxJava):
networkClient.token() // 返回 Observable<String>,在訂閱時請求 token,并在響應后發送 token
.flatMap(new Func1<String, Observable<Messages>>() {
@Override
public Observable<Messages> call(String token) {
// 返回 Observable<Messages>,在訂閱時請求消息列表,并在響應后發送請求到的消息列表
return networkClient.messages();
}
})
.subscribe(new Action1<Messages>() {
@Override
public void call(Messages messages) {
// 處理顯示消息列表
showMessages(messages);
}
});
傳統的嵌套請求需要使用嵌套的 Callback 來實現。而通過 flatMap() ,可以把嵌套的請求寫在一條鏈中,從而保持程序邏輯的清晰。
- throttleFirst(): 在每次事件觸發后的一定時間間隔內丟棄新的事件。常用作去抖動過濾,例如按鈕的點擊監聽器: RxView.clickEvents(button) // RxBinding 代碼,后面的文章有解釋 .throttleFirst(500, TimeUnit.MILLISECONDS) // 設置防抖間隔為 500ms .subscribe(subscriber); 媽媽再也不怕我的用戶手抖點開兩個重復的界面啦。 |si rou te| 喉嚨 壓制 節流 減速 窒息
變換的原理 lift()
這些變化雖然功能不一樣,但實質上都是針對事件的處理在發送。而在RXjava的內部,他們都是基于同一個基礎的方法變化,lift(Operator)。
// 注意:這不是 lift() 的源碼,而是將源碼中與性能、兼容性、擴展性有關的代碼剔除后的核心代碼。
// 如果需要看源碼,可以去 RxJava 的 GitHub 倉庫下載。
public <R> Observable<R> lift(Operator<? extends R, ? super T> operator) {
return Observable.create(new OnSubscribe<R>() {
@Override
public void call(Subscriber subscriber) {
Subscriber newSubscriber = operator.call(subscriber);
newSubscriber.onStart();
onSubscribe.call(newSubscriber); // 這個onSubscribe是原始的OnSubScribe對象??!
}
});
}
這段代碼,它生成了一個新的Observable并且返回,新創建的Observable中的參數OnSubscribe的回調方法call()的實現,和Observable.Subscribe()基本一樣,但是是由區別的。
不一樣的地方在與OnSubscrvable中call(subscribe)所指代了對象不同
- 當使用lift方法時,
- 假設有一個Observable<T>調用了lift()并創建Observable后,一共有個Observable。
- 同樣的Observable的參數OnSubscribe,加上之前原始的Observable里面的原始OnSubscribe,也就有了兩個 OnSubscribe;
- 然后調用Observable.create傳入Observable<R>,觸發onSubscribe的Call方法,也是就override的方法,
- 在該方法中 調用了OnSubscribe.call()方法,注意:這個OnSubscribe方法是原始的Observable<T>的onSubscribe<T>對象。他需要傳入一個Subscriber對象,這個對象是通過Subscriber newSubscriber = operator.call(subscriber);operator.call()方法生成的新的Subscribe。正是這個operator對象將兩個Subscriber對象聯系起來的。OnSubscribe<T>在執行Subscriber<R>.onNext(R r),而這里從T變成R,正好用到了傳到Operator中的參數Func1<T, R>。
這樣就實現了 lift() 過程,有點像一種代理機制,通過事件攔截和處理實現事件序列的變換。
也可以這個說:在Observable執行了lift(Operator)方法后,會返回一個新的Observable,這個新的Observable會象一個代理一樣,負責接受原始的Observable發出的事件,并在處理后發送給Subscriber
[圖片上傳失敗...(image-8fc12c-1512961567324)]
[圖片上傳失敗...(image-925ff1-1512961567324)]
多次調用
[圖片上傳失敗...(image-eb30f8-151296156732
舉個例子
Observable.just(1.34f, 8.3453f, -534.34f, 392.99f)
.map(new Func1<Float, Integer>() {
@Override
public Integer call(Float aFloat) {
return Math.round(aFloat);
}
})
.map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return Integer.toBinaryString(integer);
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
log("2 map onNext->" + s);
}
});
// outputs
// 2 map onNext->1
// 2 map onNext->1000
// 2 map onNext->11111111111111111111110111101010
// 2 map onNext->110001001
該例子是一個Float->Integer->String的轉換。我們按上面的流程來分析。
- 生成一個Observable<Float>
- 調用map生成Observable<Integer>
- 調用map生成Observable<String>
- subscribe()傳入一個Subscribe(String),至此流的前半部分全部完成。
- 執行開始,Subscribe<String>發送事件,先生成一個Subscrver<Integer>傳給Observable<Integer>(Observable<Integer>.onSubscribe.call())。
- Observable<Interger>開始發送事件,同樣生成一個Subscriber<Float>傳給Observable<Float>(Observable<Float>.onSubscribe.call())。
- 真正的發送事件開始,Observable<Float>調用Subscriber<Float>.onNext(Float)等方法,同時Subscriber<Integer>.onNext(Integer)被調用,同時Subscriber<String>.onNext(String)被調用,事件發送完成。
compose對Observable整體的變換 |com pou si| 構成 組成
除了lift方法外,Observable還有一個變換方法叫 compose(Transformer)它和lift的區別在于lift是針對事件項和事件序列,而compose是針對observable自身進行變換。
假設在程序中有多個 Observable ,并且他們都需要應用一組相同的 lift() 變換。
public class LiftAllTransformer implements Observable.Transformer<Integer, String> {
@Override
public Observable<String> call(Observable<Integer> observable) {
return observable
.lift1()
.lift2()
.lift3()
.lift4();
}
}
...
Transformer liftAll = new LiftAllTransformer();
observable1.compose(liftAll).subscribe(subscriber1);
observable2.compose(liftAll).subscribe(subscriber2);
observable3.compose(liftAll).subscribe(subscriber3);
observable4.compose(liftAll).subscribe(subscriber4);
像上面這樣,使用 compose() 方法,Observable 可以利用傳入的 Transformer 對象的 call 方法直接對自身進行處理,也就不必被包在方法的里面了。
Scheduler的API(二)
利用 subscribeOn() 結合 observeOn() 來實現線程控制,讓事件的產生和消費發生在不同的線程。
能不能可以多次切換線程
答案是能。因為ObserveOn指定的是
操作符分類
面我按類別把常用操作符分別介紹,其實很多內容都是來自于ReactiveX的官方網站,英文比較好的朋友可以參考(http://reactivex.io/)。
按照官方的分類,操作符大致分為以下幾種:
Creating Observables(Observable的創建操作符),比如:Observable.create()、Observable.just()、Observable.from()等等;
Transforming Observables(Observable的轉換操作符),比如:observable.map()、observable.flatMap()、observable.buffer()等等;
Filtering Observables(Observable的過濾操作符),比如:observable.filter()、observable.sample()、observable.take()等等;
Combining Observables(Observable的組合操作符),比如:observable.join()、observable.merge()、observable.combineLatest()等等;
Error Handling Operators(Observable的錯誤處理操作符),比如:observable.onErrorResumeNext()、observable.retry()等等;
Observable Utility Operators(Observable的功能性操作符),比如:observable.subscribeOn()、observable.observeOn()、observable.delay()等等;
Conditional and Boolean Operators(Observable的條件操作符),比如:observable.amb()、observable.contains()、observable.skipUntil()等等;
Mathematical and Aggregate Operators(Observable數學運算及聚合操作符),比如:observable.count()、observable.reduce()、observable.concat()等等;
其他如observable.toList()、observable.connect()、observable.publish()等等;