简体   繁体   English

如何使用反应式android和改造进行多个请求

[英]How to make multiple requests with reactive android and retrofit

I have presenter which calls getShops() method. 我有演示者调用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);

In data layer I have Interactor which makes request to server with Retrofit and return List<Shop> . 在数据层中,我有一个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();
        }
    });
}

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. 问题是我需要使用不同的页面参数发出多个相同的请求,因为服务器每页返回N个商店,并且我需要收集所有商店,然后将Observable<List<Shop>>给演示者。

I'm new to Reactive programming, maybe there is some operator which allows to do this. 我是Reactive编程的新手,也许有一些操作员可以这样做。

Any help would be appreciated. 任何帮助,将不胜感激。

Just use Observable.range and concatMap your calls with it. 只需使用Observable.rangeconcatMap调用。 If you don't know your upper range, you can use takeUntil with some condition. 如果您不知道上限,可以在某些情况下使用takeUntil

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: 如果只需要一个onNext调用,则可以在takeUntil之后添加它:

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

You can achieve that with Observable.concat method. 您可以使用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);

Your getData method should accept pageNum parameter: 您的getData方法应接受pageNum参数:
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. 因为正如我所见,页面计数可能不同,但是concat仅用于可观察对象的静态计数。

You may try to solve that with building observable recursively . 您可以尝试使用可观察的递归构建来解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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