1. 程式人生 > >不要打斷鏈式結構:使用 RxJava的 compose() 操作符

不要打斷鏈式結構:使用 RxJava的 compose() 操作符

編輯推薦:稀土掘金,這是一個針對技術開發者的一個應用,你可以在掘金上獲取最新最優質的技術乾貨,不僅僅是Android知識、前端、後端以至於產品和設計都有涉獵,想成為全棧工程師的朋友不要錯過!

blob.png

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,和呼叫一系列的內聯操作符是一模一樣的。