1
votes

Comment faire deux requêtes en une seule requête avec rxJava2

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.


1 commentaires

Vous pouvez essayer de supprimer interactor.getTest () de flatMap et créer un fun distinct. Ensuite, appelez-le un par un au lieu d'ajouter à la requête


4 Réponses :


0
votes

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>

1 commentaires

@ Павел-Филимонов j'espère que cela vous aidera



0
votes

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

    }
}


0 commentaires

0
votes

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


        })

}


0 commentaires

0
votes

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.


0 commentaires