как выдать ошибку, а затем испустить кэшированные данные с помощью RxJava? - PullRequest
0 голосов
/ 26 мая 2018

Я использую RxJava в решении MVP, и я хочу добиться этого сценария:

  • попытаться получить данные сервера, и в случае успеха заполнить представление с использованием данных сервера

  • если его по какой-либо причине не удалось (без доступа к Интернету - недоступен сервер - внутренняя ошибка сервера) показать соответствующее сообщение , но также заполнить представление с помощью кэшированные данные .

ограничения:

  • Я не хочу использовать какой-либо дополнительный обратный вызов (RX может сделать все это)

  • Я не хочу получать доступ к локальному репо напрямую из Presenter

, что я пробовал:

в моем репо:

    override fun getRepos(userName: String, page: Int, pageSize: Int):Observable<List<Repo>> {

 return githubRemoteService.getReposList(userName, page, pageSize)
                .subscribeOn(schedulersProvider.ioThread())
                .flatMap { repos ->
                    val mappedRepos = remoteResponseMapper.mapRepoResponse(repos)
                    githubLocalService.saveRepos(mappedRepos)
                    Observable.just(mappedRepos)
                }
 .onErrorResumeNext(Observable.just(githubLocalService.getReposList(userName, page, pageSize)))
               .observeOn(schedulersProvider.mainThread())

    }

в моем докладчике:

githubInteractor.getRepos(userName, page, pageSize).subscribe(
            { repos ->
                 showReposInView(repos)
            },
            { error ->
                digestAndShowErrorInView(error)  //the problem is here - no error will be present here
            })

, как мы знаем, когда я использую onErrorResumeNext, наблюдаемый источник изменяется, но ошибка никогда не будет выдана .

как я могу сначала сгенерировать ошибку, а затем сгенерировать данные локального репо?

если это невозможно сделать, как я могу изменить свой сценарий, чтобы получить тот же сценарий?

1 Ответ

0 голосов
/ 26 мая 2018

Вы не можете использовать onError и продолжить поток.onError означает, что произошла критическая ошибка и Observable заканчивается.Вы не можете использовать это.

Есть простое решение.Вы можете обернуть свой результат в структуру, которая указывает на ошибку / данные.Например,

sealed class MyData
data class Success(val data: List<Repo>) : MyData
data class Error(val t: Throwable): MyData

Вы можете отобразить успешный ответ API на Success, а в случае ошибки (в onErrorResumeNext) вы можете создать класс Error и использовать concat для продолжениясписок локальных репо.

Таким образом, вы получаете и ошибки, и успех в onNext, и вы не разрываете цепочку.

В onNext вы можете использовать when и соответственно обрабатывать ошибку / успех.

...