多个顺序Observable,每个都有及时延迟

时间:2016-11-12 00:47:08

标签: android google-maps google-places-api rx-java rx-android

我想获得google places并且根据api限制,每个请求不能超过20个位置,而下一个请求需要先前请求的nextPageToken

问题:

  • Zip运营商会立即执行所有请求,但我需要它们在每次4 seconds呼叫之间连续且及时延迟Observable

  • Delay运算符允许等待,但实际上它会立即执行Zip次调用并在给定的延迟时间后返回结果,这是不希望的。

    < / LI>

我的来源:

LatLng some = new LatLng(31.471199, 74.234940);
Observable
        .zip(getNearByPlaces(some), getNearByPlaces(some), getNearByPlaces(some), new Func3<List<PlaceInfo>, List<PlaceInfo>, List<PlaceInfo>, List<PlaceInfo>>() {
            @Override
            public List<PlaceInfo> call(List<PlaceInfo> placeInfos, List<PlaceInfo> placeInfos2, List<PlaceInfo> placeInfos3) {
                placeInfos2.addAll(placeInfos3);
                placeInfos.addAll(placeInfos2);
                return placeInfos;
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<List<PlaceInfo>>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onNext(List<PlaceInfo> placeInfos) {
                adapter.setPlaces(placeInfos);
            }
        });

我是初学者并且大约1周前开始使用rxjava,所以你可能会遇到错误。

1 个答案:

答案 0 :(得分:1)

假设您有以下响应模型

class Response {
    private String pageToken;
    private List<PlaceInfo> places;

    //setters, getters etc
}

您有两种方法可以使用API​​

Observable<Response> getNearByPlaces(LatLng latLng) {...}
Observable<Response> getNextNearByPlaces(String pageToken) {...}

定义Transformer以获取其他位置。等待4秒钟,然后获取下一个位置并将源位置添加到响应中。

private Observable.Transformer<Response, Response> addNextPlaces() {
    return observable -> observable
            .delay(4, TimeUnit.SECONDS)
            .flatMap(sourceResponse -> getNextNearByPlaces(sourceResponse.getPageToken()),
                    ((sourceResponse, nextResponse) -> {
                        nextResponse.getPlaces().addAll(sourceResponse.getPlaces());
                        return responseNext;
                    }));
}

然后你可以用这种方式做你需要的事情

getNearByPlaces(latLng)
        .compose(addNextPlaces())
        //add here additional compose methods if you need them
        .subscribe(resultResponse -> {
            resultResponse.getPlaces() //handle result List
        }, error -> {
            //handle error
        });

P.S。请注意线程。 delay将计划程序切换为computation

P.P.S。我怀疑有一个更简单和更优雅的解决方案:)