RxJava 2.x: Должен ли я использовать Flowable или Single/Completable?
Я разрабатываю приложение для Android с использованием Clean Architecture, и я переношу его в RxJava 2.x. Я должен сделать некоторые сетевые запросы для мыльной службы, поэтому я определил интерфейс api в модуле домена:
public interface SiginterApi {
Observable<User> login(String user, String password);
...
Observable<List<Campaign>> getCampaigns(List<Long> campaignIds);
}
Я прочитал, что сетевой запрос должен быть выполнен с помощью < <21 > , из-за управления противодавлением, так как это "холодный наблюдаемый". С другой стороны, я знаю, что результат запроса будет успешным (с ответом) или ошибкой, поэтому я не знаю, следует ли использовать Flowable
или Single
или даже Observable
.
Кроме того, у меня есть доступ к базе данных следующим образом:
public interface UserRepository extends Repository {
Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
...
Observable<User> findUser(String username, String hashedPassword);
}
Я не знаю, следует ли использовать Completable
/Flowable
/Observable
в методе saveUser
и Single
/Flowable
/Observable
в методе findUser
.
Ответы
Ответ 1
Противодавление - это то, что вы получаете, когда источник Observable
испускает элементы быстрее, чем Subscriber
может их уничтожить. Это чаще всего связано с горячими наблюдаемыми, а не с холодными, такими как ваши сетевые запросы.
Я думаю, что вы должны использовать Completable
вместо Observable<Void>
в вашем методе saveUser
и использовать Single
для всех мест, где вы следуете за шаблоном запроса/ответа или ввода/вывода. Observable
следует использовать, когда вы действительно хотите непрерывный поток событий.
Ответ 2
Backpressure возникает, когда Observable
испускает элементы быстрее, чем оператор или абонент могут их использовать.
Зная, что противодавление не является проблемой в вашем случае, так как ваш Observable
будет выделять только один элемент, поэтому Flowable
не является хорошим кандидатом.
Таким образом, реальный вопрос заключается в использовании Completable
или Observable
для saveUser
и Single
или Observable
для findUser
, и здесь, поскольку ожидается только один результат (успех или неудача) ради простоты и ясности вашего API, вы должны окончательно использовать Completable
/Single
, иначе будет трудно понять, что будет испускано только одно значение, которое может ввести в заблуждение пользователей API.
Ответ 3
Хм...
Я думаю, что вопрос не тривиальный, а у вас более сложная ситуация.
Eg.
Сохранить пользователя (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>
в Single
или Flowable
, чтобы воспользоваться ответом кода с сервера