RxJava的併發實現

我們在開發App過程中,常常遇見這種需求,例如首頁,僅一個界面就要請求3個甚至更多的接口,更變態的是這些接口必須按順序請求,來以此展示返回結果,那麼這樣我們就無法用普通的併發去同時請求接口了,因爲我們無法預知各個接口的請求完成時間,普通的也是最簡單的辦法就是依次請求接口了,A接口請求完成->B接口請求完成->C接口…簡單粗暴有木有?並且在加載效率上(接口請求時間)會差很多,那麼有沒有更優雅的辦法去解決這種需求呢?那必須有,利用RxJava的Observable.zip方法即可實現併發請求!

假如ApiService中有兩個接口:

    @GET("test1")
    Observable<HttpResult<TestModel1>> test1(@QueryMap HashMap<String, String> options);

    @GET("test2")
    Observable<HttpResult<TestModel2>> test2(@QueryMap HashMap<String, String> options);

HttpResult爲自定義數據結構:

public class HttpResult<T> {

    public int status;

    public String msg;

    public T data;

}

TestModel1和TestModel2則分別爲兩個返回的數據結構!

接口封裝後的請求方法:
test1:

    Observable o1 = Observable.create((ObservableOnSubscribe<TestModel1>) emitter ->
            //接口請求
            ApiUtil.getInstance()
                    .getApiService()
                    .test1()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<HttpResult<TestModel1>>() {

                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(HttpResult<TestModel1> httpResult) {
                            emitter.onNext(httpResult.data);
                            emitter.onComplete();
                        }

                        @Override
                        public void onError(Throwable e) {
                            emitter.onNext(null);
                            emitter.onComplete();
                        }

                        @Override
                        public void onComplete() {

                        }
                    }));

注意: ObservableOnSubscribe的參數是o1 中emitter要傳遞的參數類型,也就是你接口得到的數據類型:TestModel1!

test2:

 Observable o2 = Observable.create((ObservableOnSubscribe<TestModel2>) emitter ->
            //接口請求
            ApiUtil.getInstance()
                    .getApiService()
                    .test2()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<HttpResult<TestModel2>>() {

                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(HttpResult<TestModel2> httpResult) {
                            emitter.onNext(httpResult.data);
                            emitter.onComplete();
                        }

                        @Override
                        public void onError(Throwable e) {
                            emitter.onNext(null);
                            emitter.onComplete();
                        }

                        @Override
                        public void onComplete() {

                        }
                    }));

兩個接口請求,得到兩個Observable:o1和o2!

合併:

   Observable.zip(o1, o2, new BiFunction<Object, Object, Object>() {
        @Override
        public Object apply(Object o, Object o2) throws Exception {
            TestModel1 t1 = (TestModel1) o;//o1得到的結果
            TestModel2 t2 = (TestModel2) o2;//o2得到的結果
            FinalData f=new FinalData();//最終結果合併
            f.t1=t1;
            f.t2=t2;
            return f;
        }
    }).subscribeOn(Schedulers.io()).subscribe(o -> {
            FinalData f=(FinalData)o;//獲取最終結果
            //處理數據...
    });

注意: BiFunction中的3個Obj參數,前兩個對應接口返回數據類型,最後一個對應apply方法返回的數據類型(最終結果)!

如果是3個或以上接口,那麼合併時可以根據接口數量使用Function3,Function4…

   Observable.zip(o1, o2,o3, new Function3<Object, Object, Object,Object>() {
        @Override
        public Object apply(Object o, Object o2,Object o3) throws Exception {

        }
    }).subscribeOn(Schedulers.io()).subscribe(o -> {

    });

除了zip操作符,rxjava還提供了concat,merge,join等其它合併操作符,但它們又各有不同,有興趣的可以去多瞭解一下!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章