不要打斷鏈式結構:使用 RxJava的 compose() 操作符
阿新 • • 發佈:2019-01-20
編輯推薦:稀土掘金,這是一個針對技術開發者的一個應用,你可以在掘金上獲取最新最優質的技術乾貨,不僅僅是Android知識、前端、後端以至於產品和設計都有涉獵,想成為全棧工程師的朋友不要錯過!
RxJava的另一個好處在於,我們可以清楚地看到資料是如何在一系列操作符之間進行轉換的。
1 2 3 4 5 6 7 8 9 10 11 12 |
Observable.from(someSource)
.map( new Func1<Data, Data>() { @Override public Data call(Data data) {
return manipulate(data);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( new Action1<Data>() {
@Override public void call(Data data) {
doSomething(data);
}
});
|
如何將一組操作符重用於多個數據流中呢?例如,因為希望在工作執行緒中處理資料,然後在主執行緒中處理結果,所以我會頻繁使用subscribeOn()和observeOn()。如果我能夠通過重用的方式,將這種邏輯運用到我所有的資料流中,將是一件多麼偉大的事。
糟糕的實現方式
下面這些程式碼是我在過去幾個月裡一直都在使用的,正好可以拿來當反面教材。
首先,使用schedulers(排程)建立一個方法:
1 2 3 4 |
<T> Observable<T> applySchedulers(Observable<T> observable) {
return observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
} |
然後,封裝Observable資料鏈:
1 2 3 4 5 6 7 8 9 10 |
applySchedulers(Observable.from(someSource).map( new Func1<Data, Data>() {
@Override public Data call(Data data) {
return manipulate(data);
}
})
).subscribe( new Action1<Data>() {
@Override public void call(Data data) {
doSomething(data);
}
});
|
雖然這樣做也能達到目的,但是它看起來不僅醜,還容易讓人產生困惑,applySchedulers()到底什麼鬼?它不再符合操作符鏈路式結構,所以,看起來很難理解。然而,我找不到任何辦法去格式化這段程式碼,因此,這並不尷尬。
現在,試想一下,如果在一個數據流中反覆使用的話,這個反面教材將會變得要多爛有多爛。(譯者注:OMG)
Transformers簡介
聰明的同學可能已經意識到了這個問題,但是RxJava早已提供了一種解決方案:Transformer(譯者注:有轉換器意思),一般情況下可以通過使用操作符Observable.compose()來實現。
Transformer實際上就是一個Func1<Observable<T>, Observable<R>>,換言之就是:可以通過它將一種型別的Observable轉換成另一種型別的Observable,和呼叫一系列的內聯操作符是一模一樣的。