Я занимаюсь рефакторингом некоторых частей нашего кода и не уверен, что объясняю конкретную проблему. Наши бизнес-требования следующие:
- Мы должны вызвать 4 сетевых запроса отдельно от разных представлений.
- Нам нужно дождаться завершения 4 сетевых запросов и запуска нового сетевого запроса.
Раньше все это обрабатывалось в одном классе, который был разделен на 4 разных представления. Однако я не уверен, были ли мои рассуждения правильными. Я сделал это следующим образом:
- Я бы инициализировал 4 темы воспроизведения для каждого сетевого запроса, чтобы отслеживать, когда сетевые запросы будут завершены. (Я знаю, что могу использовать RxRelay для такой логики, но в настоящее время для меня это не проблема)
fun init(){
firstTrigger : ReplaySubject<Boolean> = ReplaySubject.create()
secondTrigger : ReplaySubject<Boolean> = ReplaySubject.create()
thirdTrigger : ReplaySubject<Boolean> = ReplaySubject.create()
forthTrigger : ReplaySubject<Boolean> = ReplaySubject.create()
}
- Вот пример кода одного из 4 сетевых запросов. Я вызываю тему после успеха.
fun networkRequestNrOne() {
firstObservable = apiService.networkRequestNrOne()
compositeDisposable.add(firstObservable
.retryWhenError(5, 1)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
success -> first.onNext(true) },
{ throwable -> handleError(throwable) })
)
}
- Затем у меня есть метод, который вызывается в init этого класса. Он использует zip-оператор из RxJava для объединения всех сетевых запросов.
fun observeWhenToFire(): Observable<Boolean> {
return Observable.zip(firstTrigger, secondTrigger, thirdTrigger,
forthTrigger,
Function4<Boolean, Boolean, Boolean, Boolean, Boolean> { first, second, third,
forth ->
//handle checking if all are true for example.
})
}
Теперь я хотел бы реорганизовать его и создать 4 разных варианта использования для таких случаев и новый вариант использования, который будет включать все 4 варианта использования и возвращать объединенный ответ.
Однако мне все равно нужно использовать Rx Subjects для обработки такого сценария. Каждый UseCase будет принимать тему, привязанную к этому UseCase в качестве параметра, а UseCase, который объединяет все остальные UseCase, будет включать 4 * 1 темы. .
Есть ли способ лучше? Я даже подумал об использовании обычных обратных вызовов, и это могло бы быть даже более читаемым кодом. Я тоже использую сопрограммы, однако на этот раз я не хочу преобразовывать эту логику в сопрограммы из-за нашего уникального расширения c ustom retryWhenError :)