我需要从本地或远程加载数据。如果获取了本地数据,则不会获取远程数据。
由于本地数据可以为空(即空),我必须处理RxJava2中的null
情况,所以我在java-中Optional
util的帮助下完成8。这是代码。
String data;
Observable<Optional<String>> loadCacheData() {
return Observable.create(emitter -> {
emitter.onNext(Optional.ofNullable(null));
emitter.onComplete();
});
}
Observable<Optional<String>> loadRemoteData() {
Observable<Optional<String>> remoteObservable = Observable.create((ObservableOnSubscribe<Optional<String>>) emitter -> {
Thread.sleep(2000);
emitter.onNext(Optional.of("FromRemote"));
emitter.onComplete();
}).subscribeOn(Schedulers.io());
remoteObservable.doOnNext(s -> data = s.get());
return remoteObservable;
}
void fetchData() {
Observable.concat(loadCacheData(), loadRemoteData())
.filter(s -> s.isPresent())
.firstElement()
.subscribe(s -> System.out.println(s.get()));
}
我想知道在这种情况下是否还有其他方法可以处理null。
答案 0 :(得分:2)
您无法将null
发送至RxJava2
而不应发送,而是可以传递空数据列表。
switchIfEmpty()
方法可以在两种情况下帮助您(网络和本地呼叫)。
答案 1 :(得分:1)
我在很多项目中都看到过返回静态&#39; DEFAULT&#39;给定类的对象。我不太了解这个解决方案,但它实际上是在RxJava中处理null的其他(并不是那么罕见)方法。
它看起来像这样:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print(info)
if let pickedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
print(pickedImage)
print(pickedImage.size)
}
}
然后检查:
class Anything(...) {
companion object {
val DEFAULT = Anything(...)
}
}
Observable.fromCallable { getAnythingObject() }
.onErrorReturn { Anything.DEFAULT }
答案 2 :(得分:1)
您尝试做的似乎正是Maybe提供的内容:可以拥有或不拥有数据的来源。
以下是我看到这种方式的一个例子:
public class MaybeExample {
private final Network network;
private String cachedData;
public MaybeExample(final MaybeNetwork network) {
this.network = network;
}
// Just used for the test... you'll probably have something smarter
public void setCachedData(final String data) {
cachedData = data;
}
private Maybe<String> loadCacheData() {
return cachedData != null ? Maybe.just(cachedData) : Maybe.empty();
}
private Single<String> loadRemoteData() {
return network.getData();
}
public Single<String> fetchData() {
return loadCacheData().switchIfEmpty(loadRemoteData());
}
}
这将是一个测试,看看它在行动:
public class MaybeExampleTest {
@Mock
private Network network;
private MaybeExample maybeExample;
@Before
public void createExample() {
MockitoAnnotations.initMocks(this);
maybeExample = new MaybeExample(network);
}
@Test
public void nullCachedDataReturnsNetworkData() {
maybeExample.setCachedData(null);
final String networkValue = "FromNetwork";
when(network.getData()).thenReturn(Single.just(networkValue));
final TestObserver<String> observer = maybeExample.fetchData().test();
observer.assertValue(networkValue);
}
@Test
public void cachedDataIsReturnedWithoutCallingNetwork() {
final String cachedValue = "FromCache";
maybeExample.setCachedData(cachedValue);
when(network.getData()).thenReturn(Single.error(new UnsupportedOperationException()));
final TestObserver<String> observer = maybeExample.fetchData().test();
observer.assertValue(cachedValue);
observer.assertNoErrors();
}
}