简体   繁体   中英

How to make multiple requests with reactive android and retrofit

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.

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

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM