How to make multiple requests with reactive android and retrofit

最后都变了- 提交于 2019-12-25 07:50:13

问题


I have presenter which calls getShops() method.

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);

In data layer I have Interactor which makes request to server with Retrofit and 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();
        }
    });
}

The problem is that I need to make multiple identical requests with different page parameter, because server returns N shops per page, and I need collect all shops and then return the Observable<List<Shop>> to presenter.

I'm new to Reactive programming, maybe there is some operator which allows to do this.

Any help would be appreciated.


回答1:


Just use Observable.range and concatMap your calls with it. If you don't know your upper range, you can use takeUntil with some condition.

Something like this:

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

If you want only one onNext call you can add this after takeUntil:

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



回答2:


You can achieve that with Observable.concat method.

/**
 * 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);

Your getData method should accept pageNum parameter:
public Observable<List<Shop>> getData(int pageNum)

But it is only an answer for your particular question, which could not fullfill your needs. Because as i see there could be different count of pages, but concat is only for static count of observables.

You may try to solve that with building observable recursively.



来源:https://stackoverflow.com/questions/40807728/how-to-make-multiple-requests-with-reactive-android-and-retrofit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!