閱讀 rxjava 源代碼之 - map

上一篇文章 寫了一個(gè)極其簡化的 Rxjava Observable ,現(xiàn)在,我試圖添加一個(gè) map 操作符卫键。

public <R> Observable<R> map(Func1<T, R> func1) {
  return new Observable<R>(subscriber -> this.subscribe(new Subscriber<T>() {
      @Override
      public void onCompleted() {
          subscriber.onCompleted();
      }

      @Override
      public void onError(Throwable e) {
          subscriber.onError(e);
      }

      @Override
       public void onNext(T t) {
           R r = null;
           try {
               r = func1.call(t);
           } catch (Throwable e) {
               unsubscribe();
               return;
           }
           subscriber.onNext(r);
       }

      @Override
      public void unsubscribe() {
          subscriber.unsubscribe();
      }

      @Override
      public boolean isUnsubscribed() {
          return subscriber.isUnsubscribed();
      }
  }));
}

Java 本身語言限制,導(dǎo)致代碼臃腫虱朵。代碼的核心部分就是

return new Observable<R>(subscriber -> this.subscribe(new Subscriber<T>() {
    @Override
     public void onNext(T t) {
           R r = null;
           try {
               r = func1.call(t);
           } catch (Throwable e) {
               unsubscribe();
               return;
           }
           subscriber.onNext(r);
       }
}

這里看到以下幾點(diǎn)

  1. map 接收兩個(gè)參數(shù) 永罚,注,對于成員函數(shù)卧秘,第一個(gè)參數(shù)是 this呢袱。
  2. 第一個(gè)參數(shù)是 Observable<T> this
  3. 第二個(gè)參數(shù)是 Func1<T,R> func1;
    1. func1 接收一個(gè)參數(shù) T
    2. func1.call(t) 返回一個(gè) R
  4. map 要返回一個(gè) Observable<R> 翅敌,那么就要在 OnSubscribe 的時(shí)候羞福,需要從 this 里面得到一個(gè)個(gè) T t ,然后用 func1.call(t) 蚯涮,然后轉(zhuǎn)移給下一個(gè) subscriber治专。

因?yàn)? Java8 lambda 關(guān)鍵字的引入卖陵,我們看到函數(shù)式編程中的 variable capture 的強(qiáng)大。

這是一個(gè)非常簡化的 map 實(shí)現(xiàn)张峰,還有很多問題泪蔫。

  1. 還有非常多的操作符和 map 很類似,這里有很多重復(fù)代碼喘批。
  2. backpressure 沒有處理撩荣。
  3. unsubscribe 還沒有處理好。subscriber 鏈的關(guān)系沒有處理饶深。
  4. 異常也沒有處理好餐曹。
  5. 沒有保證 onComplete 只被調(diào)用一次 。

這個(gè)簡化的實(shí)現(xiàn)盡管有很多問題敌厘,但是可以幫助我們理解原有復(fù)雜完整的實(shí)現(xiàn)台猴。Map 的核心結(jié)構(gòu)是這樣

  1. 本身含有一個(gè) Subscriber 對象,訂閱上層的 Observable
  2. 返回一個(gè) Observable 對象俱两,提供給下層訂閱饱狂。
  3. 這種方法組合了 Observable,構(gòu)成了一個(gè)鏈條宪彩。
OnSubscribe<?> onSubscribe = subscriber /*傳遞進(jìn)來的 subscriber 參數(shù)休讳,給下層產(chǎn)生數(shù)據(jù)*/
     -> {
        /* this 是上層的 Observable,訂閱上層 */
        this.subscribe(new Subscriber<T>() {
        @Override
        public void onNext(T t) {
           R r = null;
           try {
               r = func1.call(t);
           } catch (Throwable e) {
               unsubscribe();
               return;
           }
          /* 當(dāng)上層產(chǎn)生數(shù)據(jù)的時(shí)候毯焕,經(jīng)過轉(zhuǎn)換,傳遞給下層*/
           subscriber.onNext(r);
       }
      };
Observable<R> ret = new Observable<R>(onSubscribe);
return ret;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磺樱,一起剝皮案震驚了整個(gè)濱河市纳猫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌竹捉,老刑警劉巖芜辕,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異块差,居然都是意外死亡侵续,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門憨闰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹉动,你說我怎么就攤上這事轧坎。” “怎么了缸血?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵蜜氨,是天一觀的道長。 經(jīng)常有香客問我捎泻,道長飒炎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任笆豁,我火速辦了婚禮郎汪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渔呵。我一直安慰自己怒竿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布扩氢。 她就那樣靜靜地躺著耕驰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪录豺。 梳的紋絲不亂的頭發(fā)上朦肘,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音双饥,去河邊找鬼媒抠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咏花,可吹牛的內(nèi)容都是我干的趴生。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼昏翰,長吁一口氣:“原來是場噩夢啊……” “哼苍匆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棚菊,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤浸踩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后统求,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體检碗,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年码邻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了折剃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡像屋,死狀恐怖微驶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤因苹,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布苟耻,位于F島的核電站,受9級特大地震影響扶檐,放射性物質(zhì)發(fā)生泄漏凶杖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一款筑、第九天 我趴在偏房一處隱蔽的房頂上張望智蝠。 院中可真熱鬧,春花似錦奈梳、人聲如沸杈湾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至于宙,卻和暖如春浮驳,著一層夾襖步出監(jiān)牢的瞬間捞魁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工谱俭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人昆著。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像宣吱,于是被迫代替她去往敵國和親窃这。 傳聞我的和親對象是個(gè)殘疾皇子征候,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容