RxJava - использовать переменные разных типов (результаты нескольких операторов цепочки) в лямбде «подписки» - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь переписать следующий rx-код таким образом, чтобы удалить подписку внутри другой подписки и сделать код более идиоматичным:

 private fun foo() {
        compositeDisposable.add(getApiDataObservable().subscribe({ result ->
            if (!result.isSuccess) {
                mutableLiveData.value = "errorMessage"
            } else {
                compositeDisposable.add(Observable.zip(firstObservable,
                        secondObservable,
                        BiFunction<FirstObject, SecondObject, Pair<FirstObject, SecondObject>>
                        { obj1, obj2 -> Pair(obj1, obj2) }
                ).subscribe({

                    //there I need to use result and pair values
                }, {
                    Timber.e(it)
                }))
            }
        }))
    }

Я пробовал что-то вроде этого:

private fun foo2() : Disposable {
      return  getApiDataObservable()
                .filter { result.isSuccess }
                .flatMap {
                    //it - result
                    Observable.zip(firstObservable,
                            secondObservable,
                            BiFunction<FirstObject, SecondObject, Pair<FirstObject, SecondObject>>
                            { obj1, obj2 -> Pair(obj1, obj2) })
                }.subscribe {
                    //it - Pair<FirstObject, SecondObject>
               // here I need both  - result and pair values
                },{ mutableLiveData.value = "errorMessage"}
    }

Но у меня возникло недопонимание в следующем пункте: как я могу получить значение - результат от getApiDataObservable() и пару от Observable.zip(..)позвонить в subscribe.Первая мысль, которая приходит в голову: сохранить значение result в некоторой переменной и использовать его внутри subscribe lambda.но, возможно, этого можно достичь более элегантным и more-rx способом.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Вы можете создать обертку вокруг результата, подобного этому

class CompoundResult(apiResult: Result, firstObject: FirstObject, secondObject: SecondObject)

и изменить foo2() функцию

private fun foo2() : Disposable {
    return  getApiDataObservable()
        .flatMap {
            if(!it.isSuccess) {
                Observable.error(Throwable("errorMessage"))
            } else {
                Observable.zip(firstObservable,
                        secondObservable,
                        BiFunction<FirstObject, SecondObject, CompoundResult>
                        { obj1, obj2 -> CompoundResult(it, obj1, obj2) })
            }
        }.subscribe ({
            //it - CompoundResult
            // here I need both  - result and pair values
        },{ mutableLiveData.value = it.localizedMessage })

}

Здесь я выкидываю ошибку, если result запрос API не является успешным.Это позволяет вызвать onError() вашего абонента

0 голосов
/ 24 октября 2018

Я думаю, что вы можете комбинировать и result, и pair, когда оба доступны и возвращают комбинированный объект.В приведенном ниже примере это Pair<Result, Pair<FirstObject, SecondObject>>, но, возможно, лучше создать выделенный объект.

private fun foo2() : Disposable {
      return  getApiDataObservable()
                .filter { result.isSuccess }
                .flatMap {
                    //it - result
                    Observable.zip(firstObservable,
                            secondObservable,
                            BiFunction<FirstObject, SecondObject, Pair<FirstObject, SecondObject>>
                            { obj1, obj2 -> 
                                val pair = Pair(obj1, obj2)
                                Pair(it, pair)
                            })
                }.subscribe {
                    //it - Pair<Result, Pair<FirstObject, SecondObject>>
                },{ mutableLiveData.value = "errorMessage"}
    }

Также обратите внимание, что .filter { result.isSuccess } не будет вызывать дальнейшую цепочку, если result.isSuccess = false и выне получит никакого обратного вызова.

...