1. 程式人生 > >合併多個網路請求rxjava

合併多個網路請求rxjava

在專案中出現要獲取使用者的三個部分的資訊,決定在登入後直接全部獲取儲存在本地。

在學習rxjava中,發現有多種實現方式。

剛開始採用zip:

flowable1,flowable2,flowable3分別為3個網路請求。

Flowable.zip(flowable1, flowable2, flowable3, new Function3<UserInfo, ShopInfo, UserProfile,
LoginInfo>() {
    @Override
public LoginInfo apply(UserInfo userInfo, ShopInfo shopInfo, 
UserProfile userProfile) throws Exception { LoginInfo loginInfo = new LoginInfo(); loginInfo.profile = userProfile; loginInfo.user = userInfo; loginInfo.shop = shopInfo; return loginInfo; } }).subscribeWith(new HttpResultSubscriber<LoginInfo>() { @Override public void onNext
(LoginInfo loginInfo) { callBack.setInfo(loginInfo);//回撥處理 } @Override public void onError(Throwable t) { super.onError(t); } });
由於三個請求是合併後同時傳送,因此如果有一個請求事件出錯,便進入到onError

即使有其他請求通過,也無法走到onNext

然而為了儲存其中某些請求的資料,我們需要用另一種方式把每個事件都進行處理。

剛開始採用merge

Flowable.merge(flowable1, flowable2, 
flowable3) .subscribeWith(new HttpResultSubscriber<Object>() { @Override public void onNext(Object object) {LoginInfo loginInfo = new LoginInfo(); if (object instanceof UserInfo) { loginInfo.user = (UserInfo) object; } if (object instanceof UserProfile) { loginInfo.profile = (UserProfile) object; } if (object instanceof ShopInfo) { loginInfo.shop = (ShopInfo) object; } callBack.setInfo(loginInfo);//回撥處理 } } );
但是發現retrofit的interceptor會報錯,“ java.io.InterruptedIOException: thread interrupted”,目測是傳送請求過快導致的。

查詢資料發現merge是不按順序傳送事件,更換用順序傳送的concat之後沒有出錯。

Flowable.concat(flowable1, flowable2, flowable3)
       .subscribeWith(new HttpResultSubscriber<Object>() {
                          @Override
public void onNext(Object object) {LoginInfo loginInfo = new LoginInfo();
                              if (object instanceof UserInfo) {
                                  loginInfo.user = (UserInfo) object;
}
                              if (object instanceof UserProfile) {
                                  loginInfo.profile = (UserProfile) object;
}
                              if (object instanceof ShopInfo) {
                                  loginInfo.shop = (ShopInfo) object;
}
                              callBack.setInfo(loginInfo);//回撥處理
}
                      }
       );

當然,如果每個請求之間存在先後依賴,則可以使用map或flatMap操作符

例如flowable2和flowable3需要依賴flowable1的資料,則可以利用flatmap和zip結合

略顯複雜。。

final Flowable<LoginInfo> flowable = Flowable.zip(flowable2, flowable3, new
BiFunction<ShopInfo, UserProfile, LoginInfo>() {
            @Override
public LoginInfo apply(ShopInfo shopInfo, UserProfile userProfile) throws Exception {
                LoginInfo loginInfo = new LoginInfo();
loginInfo.profile = userProfile;
loginInfo.shop = shopInfo;
                return loginInfo;//flowable2和3資料合併
}
        });
flowable1.flatMap(new Function<UserInfo, Flowable<LoginInfo>>() {
    @Override
public Flowable<LoginInfo> apply(UserInfo userInfo) throws Exception {
        LoginInfo loginInfo = new LoginInfo();
loginInfo.user = userInfo;
callBack.setInfo(loginInfo);//flowable1回撥
        return flowable;
}
}).subscribeWith(new HttpResultSubscriber<LoginInfo>() {
    @Override
public void onNext(LoginInfo loginInfo) {
        callBack.setInfo(loginInfo);//flowable2和3資料合併後的回撥
}

    @Override
public void onError(Throwable t) {
        super.onError(t);
}
});

目測還可以利用compose,後面再補充。RxJava 著實很強大。