RxHttp 優雅的實現請求串行與并行

現實開發中,一個頁面很少只有一個請求的,一般都有多個請求,有的需要串行,有的需要并行,使用傳統的方法,如果有n個接口,我們就要設置n個接口回調,如果是串行的話,還需要在當前接口成功或失敗的地方,調用下個一個請求,一個接著一個,真的是要逼死強迫癥患者,而且代碼可讀性非常的差,新人來了往往要看上半天,不好維護且容易出錯。

本文使用 RxHttp請求框架
作為案例演示,如果你不了解RxHttp,請查看 30秒上手新一代Http請求神器RxHttp

請容許我再嘮兩句:RxHttp從4月中旬開始推廣,在大家都對新的Http請求框架學不動或者懶得學的情況下,RxHttp依然收獲了一大波粉絲,目前在Github上一經有 415顆星
,其中

RxHttp 一條鏈發送請求,新一代Http請求神器

Android 史上最優雅的實現文件上傳下載及進度的監聽

這兩篇文章更是得到了得到「玉剛說」及「劉望舒」微信公眾號獨家原創發布,我想,這也是對RxHttp的一種肯定,歡迎大家體驗RxHttp,它優雅的寫法及強大的功能,相信你一定會愛上它。

gradle依賴

implementation 'com.rxjava.rxhttp:rxhttp:1.0.9'
   annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.9' //注解處理器,生成RxHttp類
   implementation 'com.rxjava.rxlife:rxlife:1.0.7'  //頁面銷毀,關閉請求,非必須

   // if you use kotlin
   kapt 'com.rxjava.rxhttp:rxhttp-compiler:1.0.9'
復制代碼

接下來,我們正是開始。

并行

現在很多頁面是這樣的,上面是Banner條,Banner條下面是數據列表(假設是學生列表),這樣就涉及到兩個接口,一個是獲取Banner條數據,另一是獲取學生列表數據,這兩個接口沒有任何關系,所以我們可以并行去實現

//Banner 的Observable對象                                                
Observable<Banner> bannerObservable = RxHttp.get("http://...")        
    .asObject(Banner.class);                                          
                                                                      
//學生的Observable對象                                                     
Observable<List<Student>> studentObservable = RxHttp.get("http://...")
    .asList(Student.class);            
                                                                      
//這里使用RxJava組合符中的merge操作符,將兩個被觀察者合并為一個                                
Observable.merge(bannerObservable, studentObservable)                 
    .as(RxLife.asOnMain(this)) //感知生命周期,自動關閉請求                        
    .subscribe(o -> {                                                 
        //請求成功,回調2次,一次是Banner數據,一次Student列表                   
        if (o instanceof Banner) {                                    
            //獲取到banner數據                                             
        } else if (o instanceof List) {                               
            //獲取到學生列表數據                                               
        }                                                             
    }, throwable -> {                                                 
        //出現異常                                                        
    }, () -> {                                                        
        //2個請求執行完畢,開始更新UI                                             
    });                                                               
復制代碼

可以看到,我們首先通過RxHttp類拿到Banner和Student的兩個Observable對象,然后通過merge操作符,將兩個Observable對象合并為一個,并訂閱觀察者,這樣就能在onNext回調中拿到Banner和Student數據,并在onComplete回調中更新UI。

可是,這樣就完了嗎?熟悉RxJava的同學應該知道,RxJava在出現異常后并且回調到onError接口時,就會停止工作,那么如果Banner接口先出現異常,豈不是收不到Student信息了?是的,那么,我們應該如何去處理呢,其實很簡單,RxJava為我們提供了異常捕獲操作符,如: onErrorResumeNext
onErrorReturn
,作用就是出現異常了,我們如何去補救它。如果你不了解RxJava錯誤處理機制,請查看RxJava錯誤處理詳解。這里,我們使用onErrorResumeNext操作符,代碼如下

//Banner 的Observable對象                                                
Observable<Banner> bannerObservable = RxHttp.get("http://...")        
    .asObject(Banner.class)
    .onErrorResumeNext(Observable.empty()); //出現異常,發送一個空的Observable對象                                         
                                                                      
//學生的Observable對象                                                     
Observable<List<Student>> studentObservable = RxHttp.get("http://...")
    .asList(Student.class);            
                                                                      
//這里使用RxJava組合符中的merge操作符,將兩個被觀察者合并為一個                                
Observable.merge(bannerObservable, studentObservable)                 
    .as(RxLife.asOnMain(this)) //感知生命周期,自動關閉請求                        
    .subscribe(o -> {                                                 
        //請求成功,回調2次,一次是Banner數據,一次Student列表                   
        if (o instanceof Banner) {                                    
            //獲取到banner數據                                             
        } else if (o instanceof List) {                               
            //獲取到學生列表數據                                               
        }                                                             
    }, throwable -> {                                                 
        //出現異常                                                        
    }, () -> {                                                        
        //2個請求執行完畢,開始更新UI                                             
    });
復制代碼

上面我們只加了 onErrorResumeNext(Observable.empty())
這一行代碼,Observable.empty()是一個不會發射任何事件的Observable對象。所以,這個時候如果Banner的Observable出現異常,就不會發射任何事件,Student 的Observable對象便可繼續執行,只是在onNext回調中,就只能收到一次Student的回調(請求成功的話),并且隨后執行onComplete回調更新UI,這樣就能保證即使Banner接口出錯了,我們依然可以正常現實學生列表數據。說的抽象一點就是保證A接口不影響B接口,但是B可以影響A接口,如果要保證A、B兩個接口互不影響,分別對A、B接口處理異常即可,如果有3個、4個甚至更多的請求,可以使用 Observable.mergeArray
操作符。

串行

接下來,看看我們串行,假設我們有這樣一個需求,需要在注冊完成后立即去登錄,這種情況下,就只能串行去實現,在這,我們使用RxJava的 flatMap
這個操作符去實現

flatMap

RxHttp.postForm("http://...") //發送注冊請求
    .add("userName", "zhangsan")
    .add("password", "123456")
    .asObject(Register.class)
    .flatMap((io.reactivex.functions.Function<Register, ObservableSource<User>>) register -> {
        //注冊成功,拿到注冊信息去登錄,并返回User對象
        return RxHttp.get("http://...") //發送登錄請求
                .add("userId", register.getUserId())
                .add("password", register.getPassword())
                .subscribeOnCurrent() //當前線程發送登錄請求
                .asObject(User.class);
    })
    .as(RxLife.asOnMain(this)) //感知生命周期,自動關閉請求
    .subscribe(user -> {
        //注冊并且登錄成功,拿到用戶信息
    }, throwable -> {
        //出現異常,注冊失敗或者登錄失敗
    });
復制代碼

注:
RxHttp中的 asXXX
系列方法,內部會默認開啟IO線程執行Http請求,所以我們在發送單個請求時,無需指定請求執行線程;然而在多個請求串行時,為提升效率,我們希望一個線程可以執行多個請求,故我們需要使用 subscribeOnCurrent
方法指定請求在當前線程執行。

可以看到,這里我們使用 flatMap
操作符,當注冊成功,就會走到flatMap內部去登錄,登錄成功就會拿到User對象并回調觀察者。

小結

看完你會發現,RxHttp做到了與RxJava的無縫連接,使用 asXXX
系列方法,就可以拿到一個 Observable<T>
對象,隨后再結合RxJava的 merge
flatMap
,就可以優雅的實現的Http請求的串行及并行。如果你對RxJava有一定的了解,還可以實現很多有意思的功能,比如:為單個請求設置超時、請求失敗自動重試n次等等。

最后,一切功勞都要歸功于RxJava的強大,感謝RxJava,向它致敬!!!!

原文 

https://juejin.im/post/5d0782dbe51d4550bf1ae861

本站部分文章源于互聯網,本著傳播知識、有益學習和研究的目的進行的轉載,為網友免費提供。如有著作權人或出版方提出異議,本站將立即刪除。如果您對文章轉載有任何疑問請告之我們,以便我們及時糾正。

PS:推薦一個微信公眾號: askHarries 或者qq群:474807195,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

轉載請注明原文出處:Harries Blog? » RxHttp 優雅的實現請求串行與并行

贊 (0)
分享到:更多 ()

評論 0

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
2013平特肖公式