如何使用反应式 android 和改造发出多个请求
How to make multiple requests with reactive android and retrofit
我有调用 getShops() 方法的演示者。
Observable<List<Shop>> observable = interactor.getData();
Subscription subscription = observable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Shop>>() {
@Override
public void onCompleted() {
view.hideProgress();
}
@Override
public void onError(Throwable e) {
super.onError(e);
view.hideProgress();
}
@Override
public void onNext(List<Shop> shops) {
handleShops(shops);
view.onSuccess();
}
});
composite.add(subscription);
在数据层中,我有 Interactor,它通过 Retrofit 和 return List<Shop>
.
向服务器发出请求
@Override
public Observable<List<Shop>> getData() {
return api.getShops(pageNum).map(new Func1<ShopWrapper, List<Shop>>() {
@Override
public List<Shop> call(ShopWrapper wrapper) {
return wrapper.getShops();
}
});
}
问题是我需要用不同的页面参数发出多个相同的请求,因为服务器 return 每个页面有 N 家商店,我需要收集所有商店然后 return Observable<List<Shop>>
给主持人。
我是 Reactive 编程的新手,也许有一些操作符允许这样做。
如有任何帮助,我们将不胜感激。
您可以使用 Observable.concat
方法实现。
/**
* Returns an Observable that emits the items emitted by two Observables, one after the other, without
* interleaving them.
*/
Observable<List<Shop>> observable = Observable.concat(
interactor.getData(0), interactor.getData(1), interactor.getData(2) //and so on);
您的 getData
方法应该接受 pageNum
参数:
public Observable<List<Shop>> getData(int pageNum)
但这只是针对您的特定问题的回答,不能满足您的需求。因为正如我所见,可能会有不同的页数,但 concat 仅用于可观察对象的静态计数。
您可以尝试解决 。
只需使用 Observable.range
和 concatMap
您的通话即可。
如果您不知道上限,可以在某些条件下使用 takeUntil
。
像这样:
Observable.range(0, Integer.MAX_VALUE)
.concatMap(pageNum -> api.getShops(pageNum).map(doYourMapping))
.takeUntil(shops -> someCondition);
如果您只需要一个 onNext 调用,您可以在 takeUntil 之后添加:
.flatMapIterable(shops -> shops)
.toList();
我有调用 getShops() 方法的演示者。
Observable<List<Shop>> observable = interactor.getData();
Subscription subscription = observable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Shop>>() {
@Override
public void onCompleted() {
view.hideProgress();
}
@Override
public void onError(Throwable e) {
super.onError(e);
view.hideProgress();
}
@Override
public void onNext(List<Shop> shops) {
handleShops(shops);
view.onSuccess();
}
});
composite.add(subscription);
在数据层中,我有 Interactor,它通过 Retrofit 和 return List<Shop>
.
@Override
public Observable<List<Shop>> getData() {
return api.getShops(pageNum).map(new Func1<ShopWrapper, List<Shop>>() {
@Override
public List<Shop> call(ShopWrapper wrapper) {
return wrapper.getShops();
}
});
}
问题是我需要用不同的页面参数发出多个相同的请求,因为服务器 return 每个页面有 N 家商店,我需要收集所有商店然后 return Observable<List<Shop>>
给主持人。
我是 Reactive 编程的新手,也许有一些操作符允许这样做。
如有任何帮助,我们将不胜感激。
您可以使用 Observable.concat
方法实现。
/**
* Returns an Observable that emits the items emitted by two Observables, one after the other, without
* interleaving them.
*/
Observable<List<Shop>> observable = Observable.concat(
interactor.getData(0), interactor.getData(1), interactor.getData(2) //and so on);
您的 getData
方法应该接受 pageNum
参数:
public Observable<List<Shop>> getData(int pageNum)
但这只是针对您的特定问题的回答,不能满足您的需求。因为正如我所见,可能会有不同的页数,但 concat 仅用于可观察对象的静态计数。
您可以尝试解决
只需使用 Observable.range
和 concatMap
您的通话即可。
如果您不知道上限,可以在某些条件下使用 takeUntil
。
像这样:
Observable.range(0, Integer.MAX_VALUE)
.concatMap(pageNum -> api.getShops(pageNum).map(doYourMapping))
.takeUntil(shops -> someCondition);
如果您只需要一个 onNext 调用,您可以在 takeUntil 之后添加:
.flatMapIterable(shops -> shops)
.toList();