使用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));
}
}
答案 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