2017-03-01 41 views
19

我正在開發一個使用Clean Architecture的Android應用程序,並將其遷移到RxJava 2.x.我必須做出一些網絡請求對SOAP服務,所以我定義域模塊中的API接口:RxJava 2.x:我應該使用Flowable還是Single/Completable?

public interface SiginterApi { 
    Observable<User> login(String user, String password); 
    ... 
    Observable<List<Campaign>> getCampaigns(List<Long> campaignIds); 
} 

我讀過一個網絡請求應以「Flowable」提出,因爲背壓因爲它是一個'冷觀察'。另一方面,我知道請求的結果將是成功的(帶有響應)或錯誤,所以我不知道我是否應該使用FlowableSingle甚至Observable

另外,我有一個數據庫訪問是這樣的:

public interface UserRepository extends Repository { 
    Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user); 
    ... 
    Observable<User> findUser(String username, String hashedPassword); 
} 

我不知道我是否應該在findUser方法saveUser方法和Single/Flowable/Observable使用Completable/Flowable/Observable

回答

16

當源Observable發射物品的速度比Subscriber消耗的速度快時,可以獲得背壓。這通常是關注觀察,而不是喜歡你的網絡請求。

我想你應該在你的saveUser方法使用Completable,而不是Observable<Void>,並使用Single對於您遵循請求/響應或輸入/輸出模式的所有地方。當您確實需要連續的事件流時,應使用Observable

+0

感謝您的回覆。我同意'Single'對於網絡請求來說是更好的選擇,因爲有單一的響應,但是你可以在這個[question](http://stackoverflow.com/a/40326875/6389621)和其他許多博客中閱讀關於RxJava 2.x,網絡和數據庫訪問器應該使用'Flowable'。 –

+1

我相信作者指的是網絡和數據庫連接,其行爲類似於一系列事件。如果我理解正確,那不同於HTTP請求/響應對或單個數據庫查詢。 – npace

+0

所以你認爲在'Observable'('Single' /'Completable')和'Flowable'之間做出決定的關鍵是你是否真的需要背壓控制。它不介意源類型(冷源,網絡/數據庫訪問...) –

11

Backpressure發生在Observable發射物品的速度比運營商或用戶能消耗的要快

由於知道背壓不是問題,因爲您的Observable只會發出一個項目,因此Flowable不是一個好的選擇。

所以真正的問題是閹使用CompletableObservablesaveUserSingleObservablefindUser和這裏只有一個結果有望爲您的API的簡單和清晰起見(成功或失敗),你應該明確請使用Completable/Single否則很難理解只有一個值可能會誤導您的API用戶。

+0

感謝您的迴應。我同意'Single'對於網絡請求來說是更好的選擇,因爲有單一的響應,但是你可以在這個[question](http://stackoverflow.com/a/40326875/6389621)和其他許多博客中閱讀關於RxJava 2.x,網絡和數據庫訪問器應該使用'Flowable'。 –

+0

[何時使用Flowable](https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2。0#時使用的流動的)。與db訪問相關的例子是我引用*通過JDBC從數據庫讀取也是阻塞和基於拉的,並且由您通過調用ResultSet.next()來控制可能的每個下游請求。*在這種情況下,我們閱讀數據庫和我們有幾個結果是不是你的情況,如果你檢查文檔,問題更多的是什麼選擇'Observable'和'Flowable',所以當你有幾個項目發射 –

0

嗯......

我覺得這個問題是不平凡的一個,同時,你必須面對更復雜的情況。

例如, 保存用戶(REST)>保存用戶(SQLlite)

你可能想的Rx流爲一體。

因此,無論你聲明

1.

Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user); 

,然後用一些:flatMap, contactMap, switchMap

2.

......或者我想可能更最好不要混淆類責任(你可以用在很多地方相同的代碼)

Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user); 

RestService.saveUser(...) 
.toFlowable() // Transform into Flowable 
.switchMap{ saveToDB() } 
.subscribeBy{ ... } 
.addTo(yourDisposable) 

3.

通過建議的方式如果你想有很好的錯誤處理,不要使用Completable。你可以很容易地包裹Retrofit.Response<Body>SingleFlowable據我所知採取從服務器

0

代碼響應的優勢,你應該使用 單:當你很肯定,你會得到一個項目,否則你會得到一個錯誤。 例如:GET - card /:id

也許:如果您不確定是否會收到物品,那麼是正確的解決方案。 例如:GET-card?牌照= xvar3

Completable:當你只想知道這個動作是否成立。 例如:PUT或DETELE

可觀察:當物品數量不是很大時。

流動性:當你不知道你會得到的物品的數量。

相關問題