2017-02-08 21 views
5

Я использую RxJava в своем приложении для Android и Модернизацию для создания сетевых запросов на сервер. Я использую RxJavaCallAdapterFactory, поэтому я могу вернуть мои запросы на переоснащение. В моем коде модифицированный объект называется «api».Chaining Singles вместе в 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 и является просто параметром body для запроса 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); 
      } 
    }); 

Edit: вы можете пойти дальше с 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

 Смежные вопросы

  • Нет связанных вопросов^_^