RxJava2 question: How Zip handles error when calli

2019-02-27 10:05发布

问题:

Suppose we have 3 services, employeeTitle, employeeName, employeeLocation. If all services three services throw error employeeTitle, employeeName and employeeLocation will service only throw 1 error? According to the documentation this should be the behavior is this correct? What happens if only employeeTitle throws error and the other services are successful? As per my understanding if employeeTitle throws an exception then zip will still throw 1 exception only and this exception will be employeeTitle's service error. Am I in the right track?

-In my code below, I am expecting the zip error to come in the first onErrorResumeNext inside getEmployeeInfo()

Single<Model> getCompositeEmployeeInfo(){ 
  return Single.zip(
     api.employeeTitle()
       .subscribeOn(Schedulers.newThread()),
     api.employeeName()
       .subscribeOn(Schedulers.newThread()),
     api.employeeLocation()
       .subscribeOn(Schedulers.newThread()),
     new Function3<EmployeeTitle, EmployeeName, EmployeeLocation>() {

     @public Model apply(EmployeeTitle empTitle, EmployeeName empName,
                         EmployeeLocation empLocation){
       //some logic
     }

Single<Model2> getEmployeeInfo(){  
return getCompositeEmployeeInfo()
        .observeOn(AndroidSchedulers.mainThread())
        .onErrorResumeNext(throwable-> { 
           return Single.error(throwable}//I am expecting only 1 error(if 
            //more than one error is thrown) from 
            //zip, either employeeTitle, employeeName or employeeLocation.
         )
         .flatMap(model -> {
                 //some logic
           return getEmployeePreference();
                    .observeOn(AndroidSchedulers.mainThread())
                    .onErrorResumeNext(throwable -> {
                       return Single.error(throwable);
                    })
                   .flatMap(employeePreference -> {
                      //some logic
                      return Single.just(result);
           });  } }

回答1:

The "reactive contract" states that there can only be one terminating condition, either onError or onComplete. When you combine multiple observer chains with zip(), termination conditions from the three observer chains are combined into one.

If an error is raised by the first observer chain, there is still a possibility that errors can be raised in the other two. However, only the first error is emitted by the zip() operator. In addition, since the observer chains run on separate threads, there will be a race to see which error gets reported; it is non-deterministic.

Errors that are raised in an observer chain after the chain has terminated, or when there is no longer a way to handle the error down-stream, are passed to a global handler.