2017-02-08 75 views
5

我在我的android應用程序中使用RxJava以及向網站添加服務器請求。我正在使用RxJavaCallAdapterFactory,所以我可以讓我的改造請求返回單曲。在我的代碼中,改造對象被命名爲'api'。在RxJava鏈接單打一起

這裏的代碼工作正常,但在本例中,我需要檢索userId,然後才能製作播放列表。我將userId請求平面映射到API請求,在製作播放列表之後,我需要再次使用平面地圖將JSON響應轉換爲可用對象。

public JSONUser me; 

public Single<String> getUserId(){ 

    if(me != null){ 
     return Single.just(me.getUserId()); 
    } 

    return api.getMe().flatMap(new Func1<JSONUser, Single<String>>() { 
     @Override 
     public Single<String> call(JSONUser meResult) { 
      me = meResult; 
      return Single.just(me.getUserId()); 
     } 
    }); 
} 

public Single<Playlist> createPlaylist(String name) { 

    final NewPlaylistConfig config = new NewPlaylistConfig(name); 

    return getUserId().flatMap(new Func1<String, Single<Playlist>>() { 
     @Override 
     public Single<Playlist> call(String userId) { 
      return api.createPlaylist(userId, config).flatMap(
        new Func1<JSONPlaylist, Single<? extends SpotifyPlaylist>>() { 
         @Override 
         public Single<? extends Playlist> call(JSONPlaylist data) { 
          return Single.just(new Playlist(data)); 
        } 
      }); 
     } 
    }); 
} 

這裏的入口點是createPlaylist()。 NewPlaylistConfig將被轉換爲JSON,並且只是POST請求的主體參數。 UserId是一個路徑參數。

這裏我的主要問題是,如果有一種方法可以鏈接這些操作,而不需要在這裏看到的「回調 - 地獄」。就像我說的,這段代碼有效,但它確實很難看。如果有人能指出我在這個正確的方向,我將不勝感激。有沒有辦法讓這項工作像承諾一樣,你可以鏈接神祕的東西?

謝謝。

+0

這是否stackoverflow.com/questions/30269011/chain-two-retrofit-observables-w-rxjava幫助? – Raghunandan

回答

7

相反的:

getUserId() 
    .flatMap(new Func1<String, Single<Playlist>>() { 
     @Override 
     public Single<Playlist> call(String userId) { 
      return api.createPlaylist(userId, config).flatMap(
       new Func1<JSONPlaylist, Single<? extends SpotifyPlaylist>>() { 
        @Override 
        public Single<? extends Playlist> call(JSONPlaylist data) { 
         return Single.just(new Playlist(data)); 
        } 
      }); 
     } 
    }); 

寫:

getUserId() 
    .flatMap(new Func1<String, Single<Playlist>>() { 
     @Override 
     public Single<Playlist> call(String userId) { 
      return api.createPlaylist(userId, config); 
     } 
    }) 
    .flatMap(
     new Func1<JSONPlaylist, Single<? extends SpotifyPlaylist>>() { 
      @Override 
      public Single<? extends Playlist> call(JSONPlaylist data) { 
       return Single.just(new Playlist(data)); 
      } 
    }); 

其實你可以鏈flatmap(及圖)像你再用承諾鏈條。


注意您可以替換地圖的第二flatmap,免去:

return Single.just(new Playlist(data)); 

有:

return new Playlist(data); 

結果:

getUserId() 
    .flatMap(new Func1<String, Single<Playlist>>() { 
     @Override 
     public Single<Playlist> call(String userId) { 
      return api.createPlaylist(userId, config); 
     } 
    }) 
    .map(
     new Func1<JSONPlaylist, SpotifyPlaylist>() { 
      @Override 
      public SpotifyPlaylist call(JSONPlaylist data) { 
       return new Playlist(data); 
      } 
    }); 

編輯:你可以用java 8走得更遠:

getUserId() 
    .flatMap(userId -> api.createPlaylist(userId, config)) 
    .map(data -> new Playlist(data)); 

或者科特林:

getUserId() 
    .flatMap { api.createPlaylist(it, config) } 
    .map { Playlist(it) } 
+0

這正是我所需要的,謝謝! – Jtvd78