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

Retrofit + rxJava: how to implement iterable N requests?

我在实施以下问题时遇到问题:我正在发出获取所有活动联盟的请求。然后,对于他们每个人,我都需要提出另一个请求来获取火柴。我认为可以使用 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 表达式,因为我没有在我的项目中使用它们。

我会更改 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<ArrayList<T>> 获得 Observable<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));

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

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

试试这个代码:

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

更新:

没有 lambda:

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