如何使用反应式android进行多次请求并进行改造

时间:2016-11-25 15:00:06

标签: java android retrofit rx-java rx-android

我有调用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向服务器发出请求并返回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();
        }
    });
}

问题是我需要使用不同的页面参数创建多个相同的请求,因为服务器每页返回N个商店,我需要收集所有商店,然后将Observable<List<Shop>>返回给演示者。

我是反应式编程的新手,也许有一些操作员允许这样做。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

只需使用Observable.rangeconcatMap来电即可。 如果您不了解上限,则可以在某些条件下使用takeUntil

这样的事情:

Observable.range(0, Integer.MAX_VALUE)
            .concatMap(pageNum -> api.getShops(pageNum).map(doYourMapping))
            .takeUntil(shops -> someCondition);

如果您只想进行一次onNext调用,可以在takeUntil之后添加:

.flatMapIterable(shops -> shops)
.toList();

答案 1 :(得分:0)

您可以使用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仅用于静态计数的可观察量。

您可以尝试解决with building observable recursively