RxAndroid – обращение к ошибкам с помощью оператора Zip

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

Это пример zip-оператора, который в основном выполняет 2 запроса параллельно:

Observable.zip( getObservable1() .onErrorResumeNext { errorThrowable: Throwable -> Observable.error(ErrorEntity(Type.ONE, errorThrowable)) }.subscribeOn(Schedulers.io()), getObservable2() .onErrorResumeNext { errorThrowable: Throwable -> Observable.error(ErrorEntity(Type.TWO, errorThrowable)) }.subscribeOn(Schedulers.io()), BiFunction { value1: String, value2: String -> return@BiFunction value1 + value2 }) //execute requests should be on io() thread .subscribeOn(Schedulers.io()) //there are other tasks inside subscriber that need io() thread .observeOn(AndroidSchedulers.mainThread()) .subscribe( { result -> Snackbar.make(view, "Replace with your own action " + result, Snackbar.LENGTH_LONG) .setAction("Action", null).show() }, { error -> Log.d("TAG", "Error is : " + (error as ErrorEntity).error.message) } ) private fun getObservable1(): Observable<String> { return Observable.defer { throw Throwable("Error 1") } } private fun getObservable2(): Observable<String> { return Observable.defer { throw Throwable("Error 2") } } 

Проблема с этим подходом заключается в том, что нет механизма для объединения каждой ошибки, такой как BiFunction, для случая успеха. Поэтому оператор zip запускает только первую ошибку и игнорирует остальные.

Вывод:

 D/TAG: Error is : Error 1 

Есть ли способ получить все ошибки только после завершения каждого наблюдаемого внутри zip или получения ошибки?

Моя основная цель – увидеть, какие запросы выдали ошибку, и выполнять только те, которые появляются после того, как пользователь спрашивает, хочет ли он повторить неудавшиеся запросы.

Вы можете моделировать свои наблюдаемые с помощью классов данных. Например

 sealed class Response { data class Success(val data: String) : Response() data class Error(val t: Throwable) : Response() } 

то вы можете сопоставить свои наблюдаемые с ответом следующим образом:

 val first: Observable<Response> = observable1 .map<Response> { Response.Success(it) } .onErrorReturn { Response.Error(it) } val second: Observable<Response> = observable2 .map<Response> { Response.Success(it) } .onErrorReturn { Response.Error(it) } 

и вы можете комбинировать их:

 Observable.zip( first, second, BiFunction { t1: Response, t2: Response -> Pair(t1, t2) } ).subscribe({println(it)}) во- Observable.zip( first, second, BiFunction { t1: Response, t2: Response -> Pair(t1, t2) } ).subscribe({println(it)}) 

это печатает:

(Ошибка (t = java.lang.Exception: ошибка 1), ошибка (t = java.lang.Exception: ошибка 2))

Также взгляните на эту статью .

Intereting Posts