执行多个订阅者rxjava

时间:2017-04-24 20:14:25

标签: java android rx-java

使用rxJava时遇到问题。我需要执行两次 UseCase 但使用不同的参数并在每个变量中添加响应。问题是在执行第二个 UseCase 之前有两个变量有值,但我不知道为什么。

在问题末尾回答

示例  首先执行GetCompanies - > departureTrip(有值回复),但returnTrip有值,但在执行getCompaniesReturn之前

声明变量

private GetCompanies getCompanies;
private GetCompanies getCompaniesReturn;
private SearchResponseDomain departureTrip;
private SearchResponseDomain returnTrip;

执行

getCompanies.execute(new CompaniesObserver());
getCompaniesReturn.execute(new CompaniesTravelDoubleObserver());

GetCompanies

public class GetCompanies extends UseCase {

    private final AppRepository repository;
    private String origin;
    private String destination;
    private String date;
    private String passengers;

    @Inject
    public GetCompanies(AppRepository repository) {
        this.repository = repository;
    }

    @Override
    protected Observable buildObservableUseCase() {
        return this.repository.getAllResultsSearch(origin, destination, date, passengers);
    }
}

用例

public abstract class UseCase {


    private Subscription subscription = Subscriptions.empty();

    protected UseCase() {
    }

    @SuppressWarnings("unchecked")
    public void execute(Subscriber UseCaseSubscriber) {
        this.subscription = this.buildObservableUseCase()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(UseCaseSubscriber);
    }

    /**
     * Unsubscribes from current {@link rx.Subscription}.
     */
    public void unsubscribe() {
        if (!subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
    }

    protected abstract Observable buildObservableUseCase();
}

代码执行 getCompanies

  private final class CompaniesObserver extends 
  DefaultSubscriber<SearchResponseDomain> {
    @Override
    public void onCompleted() {
        combineResults(departureTrip,returnTrip);
    }

    @Override
    public void onError(Throwable e) {
        super.onError(e);
    }

    @Override
    public void onNext(SearchResponseDomain searchResponseDomain) {
        super.onNext(searchResponseDomain);
        departureTrip = searchMapper.reverseMap(searchResponseDomain);
    }
}

代码执行 CompaniesTravelDoubleObserver

    private final class CompaniesTravelDoubleObserver extends 
    DefaultSubscriber<SearchResponseDomain> {
    @Override
    public void onCompleted() {
        super.onCompleted();
        combineResults(departureTrip,returnTrip);
    }

    @Override
    public void onError(Throwable e) {
        super.onError(e);
    }

    @Override
    public void onNext(SearchResponseDomain searchResponseDomain) {
        super.onNext(searchResponseDomain);
        returnTrip = searchMapper.reverseMap(searchResponseDomain);
    }
}

方法验证数据已完成

 public void combineResults(SearchResponsePresentation departureTrip,SearchResponsePresentation returnTrip){

        if(departureTrip != null && returnTrip != null){
            getView().hideLoading();
            getView().showCompanies(departureTrip,returnTrip );
        }
    }

解决方案

在阅读和阅读帖子和discutions之后,我找到了一个解决方案,帮助用户@Hans Wurst

1 - 我有问题,我没有访问观察者,我需要在演示者中订阅

GetCompanies

public class GetCompanies //extends UseCase {
{
    private final AppRepository repository;
    private String origin;
    private String destination;
    private String date;
    private String passengers;

    @Inject
    public GetCompanies(AppRepository repository) {
        this.repository = repository;
    }

    //@Override
    public Observable buildObservableUseCase() {
        return this.repository.getAllResultsSearch(origin, destination, date, passengers);
    }


    public void setOrigin(String origin) {
        this.origin = origin;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public void setPassengers(String passengers) {
        this.passengers = passengers;
    }
}

演示

  Observable<SearchResponseDomain> departureTrip  =    getCompanies.buildObservableUseCase().subscribeOn(Schedulers.io());
            Observable<SearchResponseDomain> returnTrip     =    getCompaniesReturn.buildObservableUseCase().subscribeOn(Schedulers.io());
            // Subs. to both observables. If one finishes -> whole stream closes
            Observable<List<SearchResponseDomain>> zip = Observable.zip(departureTrip, returnTrip, (d, r) -> {
                return Arrays.asList(d, r);
            });
            // Subscribe
            zip.observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new CompaniesTravelDoubleObserver());

   //------------------------------------------------------------//
private final class CompaniesTravelDoubleObserver extends 
DefaultSubscriber<List<SearchResponseDomain>> {
    @Override
    public void onCompleted() {
        getView().hideLoading();

    }
    @Override
    public void onError(Throwable e) {
        getView().hideLoading();
        networkError.setError(e);
        getView().hideLoading();
        getView().showError(networkError.getAppErrorMessage());
    }

    @Override
    public void onNext(List<SearchResponseDomain> searchResponseDomains) {
        getView().showCompanies(searchMapper.reverseMap(searchResponseDomains));

    }
}

1 个答案:

答案 0 :(得分:1)

我会回答这个问题: *将有两个不同的getCompany请求。如果两个请求都在(两者都返回一个值 - >单个),则结果必须显示在UI中。

zip操作符将来自一个流的每个值与来自另一个流的值组合在一起。

请注意,在大多数情况下,应该在运营商上构建可观察量,并且应该在您订阅的地方占用很少的地方。

@Test
public void name() throws Exception {
    Observable<SearchResponseDomain> departureTrip = getCompanies();
    Observable<SearchResponseDomain> returnTrip = getCompanies();

    // Subs. to both observables. If one finishes -> whole stream closes
    Observable<List<SearchResponseDomain>> zip = Observable.zip(departureTrip, returnTrip, (d, r) -> {
        return Arrays.asList(d, r);
    });

    // Subscribe
    zip.observeOn(AndroidSchedulers.mainThread())
            .subscribe(searchResponseDomain -> {
                // show stuff in UI
            });

}

// TODO: add params to getCompanies...
private Observable<SearchResponseDomain> getCompanies() {
    return Observable.just(new SearchResponseDomain());
}

class SearchResponseDomain {

}

我希望我从上面的代码中捕获了你的意图。如果您想获得干净的UI体验,请查看Jake Wharton的演示文稿:https://speakerdeck.com/jakewharton/the-state-of-managing-state-with-rxjava-devoxx-us-2017