Rx Java ConcatArrayDelayError и фильтры: возвращает ошибку только в случае сбоя обоих источников - PullRequest
0 голосов
/ 04 апреля 2020

Я новичок в Rx Java и после нескольких дней пробовать все, что я смог найти в Интернете, я вижу, что мне действительно нужна помощь с этим. и удаленные источники. Я добавил несколько операторов, чтобы вернуть мой удаленный источник в приоритет (через debounce) и отфильтровать ошибки, чтобы он возвращал только 1 из 2, если удаленный источник недоступен или база данных пуста.

Это работает хорошо, если что-то возвращается одним из двух моих источников, но проблема возникает, если оба источника возвращают ошибки: когда я отфильтровываю ошибки, ничего не возвращается, и моя подписка никогда не вызывается.

Может быть, есть простое решение, но я до сих пор не нашел его, кто-нибудь может помочь?

Вот мой fetchMember () в моем репозитории:

override fun fetchMember(): Observable<MemberModel?> {
    return Observable.concatArrayDelayError(memberLocalSource.fetchMember(), memberRemoteSource.fetchMember())
            .doOnNext { member ->
                saveMember(member!!)
            }
            .materialize()
            .filter { !it.isOnError }
            .dematerialize { it -> it }
            .debounce(400, TimeUnit.MILLISECONDS)
   }

А вот моя модель представления :

fun fetchToken(username: String, password: String) {
    val loginDisposable = authApiService.loginWithJWT(username, password)
            .flatMap {
                isAuthenticated = isTokenValid(username, password, it)
                sharedPreferences.setHasValidCredentials(isAuthenticated)
                memberRepository.fetchMember()
            }
            .subscribeOn(Schedulers.io())
            .observeOn((AndroidSchedulers.mainThread()))
            .doOnError { throwable ->
                throwable.printStackTrace()
            }
            .subscribe(
                    { member -> 
                        memberLiveData.value = member
                        this.memberId = member!!.id.toString()
                        this.memberName = member.name.split(" ")[0]
                        if(isAuthenticated) {
                            authenticationState.value = AuthenticationState.AUTHENTICATED_VALID_MEMBER
                        } else {
                            authenticationState.value = AuthenticationState.UNAUTHENTICATED_VALID_MEMBER
                        }
                    },
                    { error ->
                        if(isAuthenticated) {
                            authenticationState.value = AuthenticationState.AUTHENTICATED_INVALID_MEMBER
                        } else {
                            authenticationState.value = AuthenticationState.INVALID_AUTHENTICATION
                        }
                    })
    disposable.add(loginDisposable)
}

private fun isTokenValid(username: String, password: String, authResponse: AuthModel): Boolean {
    return if (authResponse.data != null) {
        false
    } else {
        tokenInterceptor.token = authResponse.token
        val tokenWithCredentials = AuthModel(authResponse.token, null, null, username, password)
        tokenRepository.saveToken(tokenWithCredentials)
        true
    }
}

1 Ответ

0 голосов
/ 05 апреля 2020

В конце концов мне удалось заставить его работать, добавив:

 .defaultIfEmpty(MemberModel(-1)) 

и проверив id == -1.

...