Observable.zip()异步执行

时间:2017-05-30 13:15:54

标签: android retrofit rx-java

我使用RxJava,Retrofit和Clean Architecture对Android应用程序进行编码。问题是我有一个Interactor / UseCase需要返回最喜欢的球队和最喜欢的球员的集合。最喜欢的团队的集合是一个端点与另一个端点混合的结果。最喜欢的球员也一样。在Interactor / UseCase实现中,我做了类似这样的事情:

getTeams = Observable.merge(mNetworkRetrofitService.getAllTeams(), mNetworkRetrofitService.getAllFavoriteTeams());
getPlayers = Observable.merge(mNetworkRetrofitService.getAllPlayers(), mNetworkRetrofitService.getAllFavoritePlayers());

然后我将这两个响应压缩在一起,将它们返回到一个包装器对象中:

Observable.zip(getTeams, getPlayers, new Func2<List<Team>, List<Player>, Pair<List<Team>, List<Player>>>() {
    @Override
    public Pair<List<Team>, List<Player>> call(List<Team> teamList, List<Player> players) {
        return new Pair<>(teamList, players);
    }
}).subscribe(new DefaultSubscriber<Pair<List<Team>, List<Player>>>() {

    @Override
    public void onNext(Pair<List<Team>, List<Player>> pair) {
        callback.showResultOnUI(pair);
    }

});

我知道.zip()方法应该等到两个rx.Observables结束发出项目,但在这种情况下混合方法正在执行多次。

我的问题是;有没有办法让zip的合并方法不被执行多次?

请记住这些事情:

  • 我简化了这个例子。我实际上还将缓存rx.Observable与Retrofit的rx.Observables合并。

  • 端点无法更改。包装器对象无法更改。必须在sigle对象包装器中将响应返回到te UI。我们无法通过两种不同的回调方式发送喜爱的球队和最喜欢的球员。

1 个答案:

答案 0 :(得分:1)

因此,您的zip方法会被多次调用,因为您对List<T>采取行动。这意味着这个Observable:

getTeams = Observable.merge(
      mNetworkRetrofitService.getAllTeams(), 
      mNetworkRetrofitService.getAllFavoriteTeams());

将有2个项目,每个项目都是一个列表 - 它不会将它们全部合并在一起。你想要的是将两个列表合并为一个:

getTeams = Observable.merge(
      mNetworkRetrofitService.getAllTeams(), 
      mNetworkRetrofitService.getAllFavoriteTeams())
.flatMap(Observable::fromIterable()
.toList();

如果您对这两个zip参数执行此操作,那么您将只获得一次发射。