2017-09-21 5 views
0

Je suis en train d'écrire une application Android qui doit effectuer 2 requêtes en ordre suivant:La fusion de plusieurs Singles pour former un Observable

  1. Faire une demande (appelons-le Requesta) à une bibliothèque qui retourne une Single<List<String>> urls.
  2. D'après ce que je reçois de RequestA, je dois faire une requête (RequestB) à une autre bibliothèque en utilisant chacune de ces URLs. Chacun des RequestB renvoie maintenant un Single.

Maintenant, j'ai combiner tous les simples de tous les RequestB pour former un observable.

Quelque chose comme Observable.mergedelayerror(List<Single>). Je ne peux pas faire cela parce que mergedelayerror attend iterable de ObservableSource.

Je sais que je peux y parvenir en mettant en œuvre callbacks et en utilisant une logique laide mais je suis vraiment à la recherche d'une solution en utilisant uniquement les opérateurs fournis par RX

Répondre

1

Vous avez besoin Observable.fromIterable(). Essayez ceci:

Java 8:

public interface Api { 

    Single<List<String>> urls(); 

    Single<String> url(String url); 
} 

private Api api; 

public void request() { 
    api.urls() 
      .flatMapObservable(Observable::fromIterable)//Observable<String> 
      .flatMapSingle(api::url) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(); 
} 

Non Java 8:

api.urls() 
     .flatMapObservable(new Function<List<String>, ObservableSource<? extends String>>() { 
      @Override 
      public ObservableSource<? extends String> apply(@NonNull List<String> source) throws Exception { 
       return Observable.fromIterable(source); 
      } 
     }) 
     .flatMapSingle(new Function<String, SingleSource<? extends String>>() { 
      @Override 
      public SingleSource<? extends String> apply(@NonNull String url) throws Exception { 
       return api.url(url); 
      } 
     }) 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(); 

Kotlin:

api.urls() 
     .flatMapObservable { Observable.fromIterable(it) } 
     .flatMapSingle { api.url(it) } 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe() 

Je vous suggère d'utiliser Java 8 ou passez à Kotlin. Ce sera beaucoup plus agréable à utiliser.

+0

J'essaie de comprendre comment chacun de ces opérateurs fonctionnera quand je n'utilise pas Java 8. Merci! –

+0

Voir les réponses aux questions. –

+0

Merci pour le partage. Bon à apprendre sur ces nouveaux opérateurs. –

1

Voici un exemple de Kotlin expliqué. La version java sera presque identique. Vous pouvez regarder des diagrammes de marbre pour ces opérateurs pour le rendre visuellement plus facile de voir ce qui se passe. Pouvez-vous partager une solution sans utiliser de références de méthode ou expliquer le fonctionnement de cette solution?

getData() //<--- original api call that returns a list of urls                                     
    .flatMapObservable { list ->                                            
     //<- Since we are on a single we have to convert to an observable to emit each item onto the stream                         
     Observable.fromIterable(list) // <-- create that observable that emits each item                              
    }                                                   
    .flatMapSingle { url ->                                             
     // we a single url entering here and have add it's result onto the stream but since it's a single we use flatMapSingle instead                  
     secondApi(url) // we call our second api here                                       
    }                                                   
    .toList() // <-- you may want to group them into a list                                     
    .subscribeOn(Schedulers.io()) // <-- causes the work to be done on the io scheduler so that you don't hit network on mainthread exception nor slow down the ui           
    .observeOn(AndroidSchedulers.mainThread()) // <-- causes the outcome to be on the ui thread so you can safely update without getting an illegal state exception can't update the ui from a now ui thread 
    .subscribe { next, error ->                                            
     next?.let {                                               
      //add to an adapter or something else                                        
     } 
     error?.let{ 
      // handle error 
     }                                              
    } 
+0

Merci pour votre réponse. Vos commentaires m'ont aidé à mieux comprendre le code. –

+0

Vous êtes les bienvenus :) –

+0

@DhruvJagetiya Si vous souhaitez en savoir plus sur RxJava consultez ce guide: http://blog.jimbaca.com/essential-rxjava-guide-for-android-developers/ –