Loading data from multiple sources with RxJava
Suppose I have some Data
I'd like to present an implementation of this setup usingRxJava.
Basic Pattern
Given an Observable
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 memory = ...;
Observable disk = ...;
Observable network = ...;
// Retrieve the first source with data
Observable 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 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.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
// Our sources (left as an exercise for the reader)
Observable memory = ...;
Observable disk = ...;
Observable network = ...;
// Retrieve the first source with data
Observable source = Observable
.concat(memory, disk, network)
.first();
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 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.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.