Loading data from multiple sources with RxJava

Simply copy from Loading data from multiple sources with RxJava

Suppose I have some Data

  • that I query from the network. I could simply hit the network each time I need the data, but caching the data on disk and in memory would be much more efficient.
  • More specifically, I want a setup that:
    Occasionally performs queries from the network for fresh data.
    Retrieves data as quickly as possible otherwise (by caching network results).

I'd like to present an implementation of this setup usingRxJava.

Basic Pattern

Given an Observable<Data> for each source (network, disk and memory), we can construct a simple solution using two operators, concat() and first().

concat() takes multiple Observables and concatenates their sequences. first() emits only the first item from a sequence. Therefore, if you use concat().first(), it retrieves the first item emitted by multiple sources.

Let's see it in action:

// Our sources (left as an exercise for the reader)
Observable<Data> memory = ...;  
Observable<Data> disk = ...;  
Observable<Data> network = ...;

// Retrieve the first source with data
Observable<Data> source = Observable  
  .concat(memory, disk, network)
  .first();

The key to this pattern is that concat() only subscribes to each child Observable when it needs to. There's no unnecessary querying of slower sources if data is cached, sincefirst() will stop the sequence early. In other words, if memory returns a result, then we won't bother going to disk or network. Conversely, if neither memory nor disk have data, it'll make a new network request.

Note that the order of the source Observables in concat() matters, since it's checking them one-by-one.

Stale Data

Unfortunately, now our data-saving code is working a little toowell! It's always returning the same data, no matter how out-of-date it is. Remember, we'd like to go back to the server occasionally for fresh data.

The solution is in first(), which can also perform filtering. Just set it up to reject data that isn't worthy:

Observable<Data> source = Observable  
  .concat(memory, diskWithCache, networkWithSave)
  .first(data -> data.isUpToDate());

Now we'll only emit the first item that qualifies as up-to-date. Thus, if one of our sources has stale Data, we'll continue on to the next one until we find fresh Data.

first() vs. takeFirst()

As an alternative to using first() for this pattern, you could also use [takeFirst()(http://reactivex.io/RxJava/javadoc/rx/Observable.html#takeFirst(rx.functions.Func1)).

The difference between the two calls is that first() will throw a NoSuchElementException if none of the sources emits valid data, whereas takeFirst() will simply complete without exception.

Which you use depends on whether you need to explicitly handle a lack of data or not.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖坛善,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡季惯,警方通過查閱死者的電腦和手機吠各,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勉抓,“玉大人走孽,你說我怎么就攤上這事×兆矗” “怎么了磕瓷?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長念逞。 經(jīng)常有香客問我困食,道長,這世上最難降的妖魔是什么翎承? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任硕盹,我火速辦了婚禮,結(jié)果婚禮上叨咖,老公的妹妹穿的比我還像新娘瘩例。我一直安慰自己,他們只是感情好甸各,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布垛贤。 她就那樣靜靜地躺著,像睡著了一般趣倾。 火紅的嫁衣襯著肌膚如雪聘惦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天儒恋,我揣著相機與錄音善绎,去河邊找鬼。 笑死诫尽,一個胖子當(dāng)著我的面吹牛禀酱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牧嫉,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼剂跟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驹止?” 一聲冷哼從身側(cè)響起浩聋,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎臊恋,沒想到半個月后衣洁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡抖仅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年坊夫,在試婚紗的時候發(fā)現(xiàn)自己被綠了砖第。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡环凿,死狀恐怖梧兼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情智听,我是刑警寧澤羽杰,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站到推,受9級特大地震影響考赛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜莉测,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一颜骤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捣卤,春花似錦忍抽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至益涧,卻和暖如春锈锤,著一層夾襖步出監(jiān)牢的瞬間驯鳖,已是汗流浹背闲询。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浅辙,地道東北人扭弧。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像记舆,于是被迫代替她去往敵國和親鸽捻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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