Retrofit + rxJava:如何实现可迭代的N个请求?

时间:2015-07-23 06:34:46

标签: java android retrofit rx-java

我有一个问题是要实现以下问题:我正在提出取得所有活跃联赛的请求。然后,对于他们中的每一个,我需要再次请求获取匹配。我认为使用flatMapIterable实现解决方案是可能的,但不知道如何实现。

目前我有以下改装接口:

public interface LeaguesApi
{
    @GET("/api/get-leagues")
    Observable<ArrayList<League>> getLeagues(@Query("active_only") boolean activeOnly);
}

public interface LeagueApi
{
    @GET("/api/get-league-fixtures/{leagueId}")
    Observable<ArrayList<Match>> getMatchesPlayed(@Path("leagueId") int leagueId, @Query("played") boolean played);
}

请告知如何遍历所有联赛,以便为每个联赛执行getMatchesPlayed。最好没有lambda表达式,因为我没有在我的项目中使用它们。

2 个答案:

答案 0 :(得分:3)

试试这段代码:

leaguesApi              // your REST adapter from retrofit
                .getLeagues(true)    // fetch leagues
                .flatMapIterable(leagues -> leagues)    //Transform from ArrayList<Liague> to Observable<Liague>
                .flatMap(l -> leagueApi.getMatchesPlayed(l.getId(), true))
                .subscribe(
                        (match) -> {/*This is onNext*/},
                        t -> t.printStackTrace(), //onError
                        () -> {/*onComplete*/}
                );

<强>更新

没有lambdas:

leaguesApi              // your REST adapter from retrofit
                .getLeagues(true)    // fetch leagues
                .flatMapIterable(new Func1<ArrayList<League>, Iterable<?>>() {
                    @Override
                    public Iterable<?> call(ArrayList<League> leagues) {
                        return leagues;
                    }
                })    //Transform from ArrayList<Liague> to Observable<Liague>
                .flatMap(new Func1<League, Observable<Match>>() {
                    @Override
                    public Observable<Match> call(League l) {
                        return leagueApi.getMatchesPlayed(l.getId(), true);
                    }
                })
                .subscribe(
                        new Action1<Match>() {
                            @Override
                            public void call(Match match) {
                                //onNext
                            }
                        },
                        new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                //onError
                            }
                        },
                        new Action0() {
                            @Override
                            public void call() {
                                //onComplete
                            }
                        }
                );

答案 1 :(得分:1)

我会更改该API,因此它会像这样读取,否则会失去很多流的灵活性:

public interface LeaguesApi
{
    @GET("/api/get-leagues")
    Observable<League> getLeagues(@Query("active_only") boolean activeOnly);
}

public interface LeagueApi
{
    @GET("/api/get-league-fixtures/{leagueId}")
    Observable<Match> getMatchesPlayed(@Path("leagueId") int leagueId, @Query("played") boolean played);
}

你能这样做吗?

如果没有,那么从Observable<T>获取Observable<ArrayList<T>>

observable.flatMapIterable(
    new Func1<ArrayList<T>, ArrayList<T>>() {
        @Override
        public ArrayList<T> call(ArrayList<T> list) {
            return list;
        }
    });

当然可以说observable.flatMapIterable(x -> x)更好。

要获得所有活跃联赛的所有比赛,请执行以下操作:

Observable<League> leagues= getLeagues(true);
Observable<Match> matches =
    leagues.flatMap( league -> getMatchesPlayed(league.leagueId, true));

或没有lambdas(我希望你没有要求)

Observable<Match> matches = leagues.flatMap(
    new Func1<League, Observable<Match>> () {
        @Override
        public Observable<Match> call(League league) {
            return getMatchesPlayed(league.leagueId, true);
        }
    });