RxJava2實現請求并發,減少請求所消耗的總時間

首先我們創建兩個Observable1 Observable2來模擬網絡請求,代碼如下:

            //每個子Observable都要加subscribeOn(Schedulers.io())指定為異步線程 不同線程來處理請求達到并發
            val observable1: Observable<String> = Observable.create(ObservableOnSubscribe<String> {
                Log.e("asd" , "observable1---"+Thread.currentThread().name)
                Thread.sleep(5000)
                it.onNext("1111")
                it.onComplete()
            }).subscribeOn(Schedulers.io())


            val observable2: Observable<String> = Observable.create(ObservableOnSubscribe<String>{
                Log.e("asd" , "observable2---"+Thread.currentThread().name)
                Thread.sleep(10000)
                it.onNext("2222")
                it.onComplete()
            }).subscribeOn(Schedulers.io())

observable1中第一行打印了線程的名字,當執行到這里的時候代表該請求已經在執行了,然后讓線程休眠5秒鐘模擬耗時,休眠過后發送一個111字符串出去調用onComplete完成本此請求

observable2中類似和observable1類似,只是休眠時間變成10秒,10秒過后請求完成發送數據,因為兩個請求由于返回數據和網絡狀態,等等原因,他們所消耗的時間肯定不一樣的。

這里需要注意 每個子的Observable必須要單獨指定線程subscribeOn(Schedulers.io()),如果不加這個,那么兩個請求還是在一個線程中執行,必定會有先后,達不到并發的效果,這里后面會展示不并發的效果

接下來吧請求合并一起使用zip關鍵字代碼如下:

            val start = System.currentTimeMillis()
            Observable.zip(observable1, observable2,BiFunction<String, String, String> { t1, t2 ->
                    Log.e("asd" , "zip:"+Thread.currentThread().name)
                    //這里是兩個請求都返回了之后 執行到這里 把數據封裝到一個類中返回,這里只是簡單的吧他們加起來返回了
                    t1 + t2
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    val end = System.currentTimeMillis() - start
                    Log.e("asd" , "請求的數據:${it}---耗時:${end}---observable:"+Thread.currentThread().name)
                }

看下打印的日志,分析一下

2019-10-25 17:18:39.143 19436-19772/com.joyrun.study E/asd: observable2---RxCachedThreadScheduler-3
2019-10-25 17:18:39.143 19436-19771/com.joyrun.study E/asd: observable1---RxCachedThreadScheduler-2
2019-10-25 17:18:49.144 19436-19772/com.joyrun.study E/asd: zip:RxCachedThreadScheduler-3
2019-10-25 17:18:49.145 19436-19436/com.joyrun.study E/asd: 請求的數據:11112222---耗時:10004---observable:main

17:18:39 同一時間打印了observable1 observable2,說明這兩個請求已經并發執行了

17:18:49 10秒鐘過后兩個請求都完成了,同一時間把數據返回主線程,打印出請求的數據:11112222---耗時:10004---observable:main
總共耗時10004 10秒 也就是說兩個請求并發了,最后拿到數據的消耗時間是倆個請求中最長的耗時時間,如果你想先執行完 就先處理的話 使用merge操作符就可以了,最后面展示用法

下面看下 不并發的情況,也就是每個子Observable不單獨指定線程,那么他們還是在同一線程中執行,打印日志中可以看到,所以必定是有一個先一個后執行的,達不到并發效果

            val observable1: Observable<String> = Observable.create {
                Log.e("asd" , "observable1:"+Thread.currentThread().name)
                Thread.sleep(5000)
                it.onNext("1111")
                it.onComplete()
            }
            val observable2: Observable<String> = Observable.create {
                Log.e("asd" , "observable2:"+Thread.currentThread().name)
                Thread.sleep(10000)
                it.onNext("2222")
                it.onComplete()
            }

解釋:使用Observable.zip將兩個Observable合并成一個指定子線程,然后在BiFunction的接口函數中就可以拿到這兩個請求返回的數據,主意執行到這里一定是兩個請求都成功返回數據了,看下打印的日志

2019-10-25 17:03:46.903 11409-11465/com.joyrun.study E/asd: observable1:RxCachedThreadScheduler-1
2019-10-25 17:03:51.905 11409-11465/com.joyrun.study E/asd: observable2:RxCachedThreadScheduler-1
2019-10-25 17:04:01.906 11409-11465/com.joyrun.study E/asd: zip:RxCachedThreadScheduler-1
2019-10-25 17:04:01.907 11409-11409/com.joyrun.study E/asd: 請求的數據:11112222---耗時:15006---observable:main

17:03:46 開始了第一個請求

17:03:51 五秒過后執行了第二個請求

17:04:01 也就是10秒過后第二個請求執行完成 就會調用到BiFunction的接口函數中做兩個請求數據的處理并返回

17:04:01 同一時間將數據返回到了主線程

打兩個請求合并之后的請求總時間15006 15秒鐘 一個5秒一個10秒,雖然請求合并了 但是沒有并發 請求所消耗的時間 還是兩個請求消耗時間的總和

如果說想并發請求,那個返回數據 就處理那個的話就是用merge操作符即可低嗎如下

            Observable.merge(observable1, observable2).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe {
                    Log.e("asd" , "請求的數據:${it}---observable:"+Thread.currentThread().name)
                }

打印日志

2019-10-25 17:28:48.586 25014-25108/com.joyrun.study E/asd: observable2:RxCachedThreadScheduler-3
2019-10-25 17:28:48.587 25014-25107/com.joyrun.study E/asd: observable1:RxCachedThreadScheduler-2
2019-10-25 17:28:53.589 25014-25014/com.joyrun.study E/asd: 請求的數據:1111---observable:main
2019-10-25 17:28:58.587 25014-25014/com.joyrun.study E/asd: 請求的數據:2222---observable:main

通過打印日志看出兩個請求并發執行,并且在不同線程中

17:28:53 5秒后執行完第一個請求拿到返回數據進行處理

17:28:58 10秒后執行完第二個請求,拿到返回數據進行處理,注意10秒后 是針對兩個請求并發處理之后的10秒 并不是第一個請求完了 后10秒

測試中完整代碼如下:

            //----------------------------------------------------------
//            val observable1: Observable<String> = Observable.create {
////                Log.e("asd" , "observable1:"+Thread.currentThread().name)
////                Thread.sleep(5000)
////                it.onNext("1111")
////                it.onComplete()
////            }
////            val observable2: Observable<String> = Observable.create {
////                Log.e("asd" , "observable2:"+Thread.currentThread().name)
////                Thread.sleep(10000)
////                it.onNext("2222")
////                it.onComplete()
////            }
            //----------------------------------------------------------


            //**********************************************************
            //每個子Observable都要加subscribeOn(Schedulers.io())指定為異步線程 不同線程來處理請求達到并發
            val observable1: Observable<String> = Observable.create(ObservableOnSubscribe<String> {
                Log.e("asd" , "observable1:"+Thread.currentThread().name)
                Thread.sleep(5000)
                it.onNext("1111")
                it.onComplete()
            }).subscribeOn(Schedulers.io())


            val observable2: Observable<String> = Observable.create(ObservableOnSubscribe<String>{
                Log.e("asd" , "observable2:"+Thread.currentThread().name)
                Thread.sleep(10000)
                it.onNext("2222")
                it.onComplete()
            }).subscribeOn(Schedulers.io())
            //**********************************************************

            
            
            //zip
//            val start = System.currentTimeMillis()
//            Observable.zip(observable1, observable2,BiFunction<String, String, String> { t1, t2 ->
//                    Log.e("asd" , "zip:"+Thread.currentThread().name)
//                    //這里是兩個請求都返回了之后 執行到這里 把數據封裝到一個類中返回,這里只是簡單的吧他們加起來返回了
//                    t1 + t2
//                }).subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe {
//                    val end = System.currentTimeMillis() - start
//                    Log.e("asd" , "請求的數據:${it}---耗時:${end}---observable:"+Thread.currentThread().name)
//                }

            
            //merge
            Observable.merge(observable1, observable2).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe {
                    Log.e("asd" , "請求的數據:${it}---observable:"+Thread.currentThread().name)
                }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • http://blog.csdn.net/yyh352091626/article/details/5330472...
    奈何心善閱讀 3,585評論 0 0
  • 在正文開始之前的最后,放上GitHub鏈接和引入依賴的gradle代碼: Github: https://gith...
    蘇蘇說zz閱讀 698評論 0 2
  • 注:只包含標準包中的操作符,用于個人學習及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,230評論 2 8
  • 一個家里,如果媽媽退步了,不再那么強勢和自以為是,那么孩子就進步了;媽媽慢了,孩子就快了;媽媽退出了,孩子就上臺了...
    姿一姿閱讀 196評論 0 2
  • 草長鶯飛處處榮 戚戚孤立于其中 春風可否也渡我 披紅掛綠添春景
    臉譜_a8d0閱讀 421評論 0 0