J'accède au serveur dans mon application Android. Je souhaite obtenir une liste de mes amis et une liste de demandes d'amis dans différentes requêtes. Ils doivent venir en même temps. Ensuite, je veux afficher ces données à l'écran.
J'ai essayé d'obtenir des données à partir de deux requêtes en utilisant flatMap.
interactor.getColleagues ()
et interactor.getTest ()
renvoie le type de données Observable
>
private fun loadColleaguesEmployer() { if (disposable?.isDisposed == true) disposable?.dispose() //запÑÐ¾Ñ Ð½Ð° ÑпиÑок дÑÑзей interactor.getColleagues(view.getIdUser() ?: preferences.userId) .subscribeOn(Schedulers.io()) .flatMap { interactor.getTest().subscribeOn(Schedulers.io()) .doOnNext { result-> view.showTest(mapper.map(result)) } } .observeOn(AndroidSchedulers.mainThread()) .subscribeBy( onNext = { result1 -> //ÐбÑабоÑка ÑпиÑка коллег ÑабоÑодаÑелей view.showColleagues(mapper.map(result1.filter { data -> data.typeFriend == "РабоÑодаÑелÑ" })) }, onError = { it.printStackTrace() } ) }
Je souhaite obtenir et traiter les données de différentes requêtes en même temps.
4 Réponses :
Zip combine les émissions de plusieurs observables ensemble via un fonction spécifiée
Vous pouvez utiliser Zip (rx Java) http: // reactivex.io/documentation/operators/zip.html , certains codes sudo ressembleront à ceci -
val firstApiObserver = apIs.hitFirstApiFunction(//api parameters) val secondApiObserver = apIs.hitSecondApiFunction(//api parameters) val zip: Single<SubscriptionsZipper>//SubscriptionsZipper is the main model which contains first& second api response model , zip = Single.zip(firstApiObserver, secondApiObserver, BiFunction { firstApiResponseModel,secondApiResponseModel -> SubscriptionsZipper(firstApiResponseModelObjectInstance, secondApiResponseModelObjectInstance) }) zip.observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(object : SingleObserver<SubscriptionsZipper> { override fun onSubscribe(d: Disposable) { compositeDisposable.add(d) } override fun onSuccess(subscriptionsZipper: SubscriptionsZipper) { Utils.hideProgressDialog() //here you will get both api response together } override fun onError(e: Throwable) { Utils.hideProgressDialog() } })J'espère que cela vous aidera.
blockquote>
@ Павел-Филимонов j'espère que cela vous aidera
Combinaison des résultats observables de plusieurs requêtes http asynchrones avec Observable.zip de rxjava.
public class Statistics { public static void main(String[] args) { List<Observable<ObservableHttpResponse>> observableRequests = Arrays.asList( Http.getAsync("http://localhost:3001/stream"), Http.getAsync("http://localhost:3002/stream"), Http.getAsync("http://localhost:3003/stream"), Http.getAsync("http://localhost:3004/stream")); List<Observable<Stats>> observableStats = observableRequests.stream() .map(observableRequest -> observableRequest.flatMap(response -> response.getContent() .map(new EventStreamJsonMapper<>(Stats.class)))) .collect(toList()); Observable<List<Stats>> joinedObservables = Observable.zip( observableStats.get(0), observableStats.get(1), observableStats.get(2), observableStats.get(3), Arrays::asList); // This does not work, as FuncN accepts (Object...) https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/functions/FuncN.java#L19 // Observable<List<Stats>> joinedObservables = Observable.zip(observableStats, Arrays::asList); joinedObservables .take(10) .subscribe( (List<Stats> statslist) -> { System.out.println(statslist); double average = statslist.stream() .mapToInt(stats -> stats.ongoingRequests) .average() .getAsDouble(); System.out.println("avg: " + average); }, System.err::println, Http::shutdown); } }
vous pouvez le faire par simple opération zip comme
fun getCricketFansObservable(): Observable<List<User>> { return RetrofitBase.getClient(context).create(Services::class.java).getCricketers().subscribeOn(Schedulers.io()) }
cette fonction combine votre réponse à partir de 2 requêtes
private fun getObservable(): Observable<List<User>> { return Observable.zip( getCricketFansObservable(), getFootlaballFansObservable(), object : BiFunction<List<User>, List<User>, List<User>> { override fun apply(t1: List<User>, t2: List<User>): List<User> { val userList = ArrayList<User>() userList.addAll(t1) userList.addAll(t2) return userList } }) }
voici un exemple de première observable
private fun callRxJava() { RetrofitBase.getClient(context).create(Services::class.java).getApiName() .subscribeOn(Schedulers.single()) .observeOn(AndroidSchedulers.mainThread()) getObservable() .flatMap(object : io.reactivex.functions.Function<List<User>, Observable<User>> { override fun apply(t: List<User>): Observable<User> { return Observable.fromIterable(t); // returning user one by one from usersList. } // flatMap - to return users one by one }) .subscribe(object : Observer<User> { override fun onSubscribe(d: Disposable) { showProgressbar() } override fun onNext(t: User) { userList.add(t) hideProgressBar() } override fun onError(e: Throwable) { Log.e("Error---", e.message) hideProgressBar() } override fun onComplete() { userAdapter.notifyDataSetChanged() } }) }
Si les deux observables renvoient le même type de données et que cela ne vous dérange pas de mélanger les données des deux sources, pensez à utiliser Observable.merge ()
Par exemple:
Observable.merge(interactor.getColleagues(), interactor.getTest()) .subscribeOn(Schedulers.io()) .subscribe( (n) -> {/*do on next*/ }, (e) -> { /*do on error*/ });
Notez que l'opérateur .merge ()
ne fonctionne pas t se soucier de l'ordre des émissions.
Vous pouvez essayer de supprimer
interactor.getTest ()
deflatMap
et créer unfun
distinct. Ensuite, appelez-le un par un au lieu d'ajouter à la requête