相關(guān)文章鏈接:
Subject
Subject是一種橋梁和代理墙懂,在ReactiveX的一些實(shí)現(xiàn)中,它既可以當(dāng)作observer也可以當(dāng)做Observable祸轮。因?yàn)樗且粋€(gè)observer九榔,所以它可以訂閱一個(gè)或多個(gè)Observable哀峻,同時(shí)因?yàn)樗且粋€(gè)Observable,它可以傳遞它觀察到的事件哲泊,重新發(fā)送他們剩蟀,它也可以發(fā)送新的事件。
當(dāng)Subject訂閱一個(gè)Observable時(shí)切威,它可以觸發(fā)Observable發(fā)送事件(如果那是一個(gè)“cold” Observable育特,以為“cold” Observable會(huì)在被訂閱之后開始發(fā)送信息)。這一特點(diǎn)可以讓Subject成為一個(gè)“hot”O(jiān)bservable,這個(gè)“hot” Observable是一種原來“cold”O(jiān)bservable的變體缰冤。
有四種不同用途的的Subject犬缨,不是這四種Subject都會(huì)在ReactiveX的所有實(shí)現(xiàn)中出現(xiàn),不同的語言都會(huì)有自己的命名規(guī)范棉浸,會(huì)略有不同怀薛。
AsyncSubject
AsyncSubject只發(fā)送由源Observable發(fā)送的最后一個(gè)事件,并且只在源Observable完成之后迷郑。(如果源Observable沒有發(fā)送任何值枝恋,AsyncSubject也不會(huì)發(fā)送任何值。)
AsyncSubject會(huì)發(fā)送相同的值給所有observer嗡害。但是焚碌,如果源Observable被一個(gè)error中斷了發(fā)送,AsyncSubject不會(huì)發(fā)送任何事件霸妹,而是會(huì)發(fā)送從源Observable傳來的error提示十电。
BehaviorSubject
當(dāng)一個(gè)observer訂閱一個(gè)BehaviorSubject,它就開始發(fā)送最近由源Observable發(fā)送的事件(或者是還沒有被發(fā)送的種子值/默認(rèn)值)然后繼續(xù)發(fā)送從源Observable接收到的其他事件叹螟。
如果源Observable被一個(gè)error中斷鹃骂,那么BehaviorSubject不會(huì)發(fā)送事件給后續(xù)的observer,但會(huì)傳遞給他們error的信息首妖。
PublishSubject
PublishSubject僅僅發(fā)送在訂閱之后由源Observable發(fā)送的數(shù)據(jù)偎漫。
PublishSubject一旦被建立就會(huì)立刻開始發(fā)送事件(除非你采取一些方法去阻止它),這種機(jī)制有丟失事件的風(fēng)險(xiǎn)有缆,因?yàn)樵赟ubject被創(chuàng)建和被監(jiān)聽之間有一定的時(shí)間間隔象踊。如果你想保證所有的事件都可以被監(jiān)聽到的話,你有兩種方法棚壁。第一種是用Create
方法(在發(fā)送之前檢查是否所有observer已經(jīng)訂閱好了)杯矩。第二種方法是你可以使用ReplaySubject。
如果源Observable被一個(gè)error中斷袖外,PublishSubject將不會(huì)發(fā)送任何事件給后續(xù)的observer史隆,但是它會(huì)傳遞error信息。
ReplaySubject
ReplaySubject發(fā)送源Observable的所有事件無論observer什么時(shí)候開始訂閱曼验。
也有一些版本的ReplaySubject會(huì)在緩存中的事件數(shù)達(dá)到一定的值時(shí)丟掉一些事件泌射,或者在某一個(gè)時(shí)間段之后丟掉一些緩存的事件。
如果把ReplaySubject當(dāng)做一個(gè)觀察者鬓照,注意不要從多個(gè)線程中調(diào)用onNext方法(或者其他on方法)熔酷,因?yàn)檫@樣的調(diào)用會(huì)導(dǎo)致非序列,ReplaySubject可能會(huì)弄不清楚哪個(gè)時(shí)間應(yīng)該首先被replay豺裆。