RxJava

2017-02-08 13 views
5

में एक साथ चेनिंग एकल एक सर्वर पर नेटवर्क अनुरोध करने के लिए मैं अपने एंड्रॉइड ऐप में आरएक्सजेवा का उपयोग कर रहा हूं। मैं RxJavaCallAdapterFactory का उपयोग कर रहा हूं, इसलिए मैं अपने रेट्रोफिट अनुरोध एकल लौटा सकता हूं। मेरे कोड में, रेट्रोफिट ऑब्जेक्ट को 'एपीआई' नाम दिया गया है।RxJava

यहां कोड ठीक काम करता है, लेकिन इस उदाहरण में, मुझे प्लेलिस्ट बनाने से पहले उपयोगकर्ता को पुनर्प्राप्त करने की आवश्यकता है। मैं एपीआई अनुरोध के लिए उपयोगकर्ता अनुरोध अनुरोध करता हूं, और प्लेलिस्ट बनाने के बाद, मुझे जेएसओएन प्रतिक्रिया को उपयोग करने योग्य ऑब्जेक्ट में बदलने के लिए फिर से फ्लैट मानचित्र का उपयोग करने की आवश्यकता है।

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

यहां प्रविष्टि बिंदु बनाना प्लेलिस्ट() होगा। NewPlaylistConfig JSON में परिवर्तित हो जाएगा और POST अनुरोध के लिए बस बॉडी पैरामीटर है। उपयोगकर्ता आईडी को पथ पैरामीटर के रूप में आवश्यक है।

मेरा मुख्य प्रश्न यहां है, यदि आप यहां "कॉलबैक-नरक" के बिना इन परिचालनों को श्रृंखलाबद्ध करने का कोई तरीका हैं। जैसे मैंने कहा, यह कोड काम करता है लेकिन यह वास्तव में बदसूरत है। अगर कोई मुझे इस बारे में सही दिशा में इंगित कर सकता है तो मैं सराहना करता हूं। क्या इस काम को ऐसे वादों की तरह बनाने का कोई तरीका है जहां आप सिर्फ चेन कर सकते हैं।

धन्यवाद।

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

,210

संपादित करें: आप जावा 8 के साथ आगे जा सकते हैं:

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

या Kotlin:

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

यह वही है जो मुझे चाहिए, धन्यवाद! – Jtvd78