如何使用rxJava2在一个请求中发出两个请求

时间:2019-06-25 11:04:13

标签: android kotlin rx-java2

我正在使用我的Android应用访问服务器。我想获取我的朋友列表和不同查询中的朋友请求列表。他们必须同时来。然后我要在屏幕上显示这些数据。

我试图在使用flatMap时从两个查询中获取数据。 interactor.getColleagues()interactor.getTest()返回数据类型Observable<List<Colleagues>>

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

我想同时获取和处理来自不同查询的数据。

4 个答案:

答案 0 :(得分:0)

  

Zip将多个Observable的排放量通过   指定功能

您可以使用 Zip(rx Java) http://reactivex.io/documentation/operators/zip.html,一些sudo代码将如下所示-

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

希望它对您有帮助。

答案 1 :(得分:0)

将多个异步http请求的可观察结果与rxjava的Observable.zip组合。

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

    }
}

答案 2 :(得分:0)

您可以通过简单的zip之类的操作来实现

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


        })

}

此功能结合了您对2个查询的答复

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
            }

        })
}

这是第一个可观察到的例子

fun getCricketFansObservable(): Observable<List<User>> {
    return RetrofitBase.getClient(context).create(Services::class.java).getCricketers().subscribeOn(Schedulers.io())
}

答案 3 :(得分:0)

如果两个观测值都返回相同的数据类型,并且您不介意将两个源数据混合在一起,请考虑使用Observable.merge()

例如:

 Observable.merge(interactor.getColleagues(), interactor.getTest())
                .subscribeOn(Schedulers.io())
                .subscribe(
                    (n) -> {/*do on next*/ },
                    (e) -> { /*do on error*/ });

请注意,.merge()操作员不在乎排放顺序。