Rx java 在RxJava2中处理null
接下来的一个重要变化是,Rx java 在RxJava2中处理null,rx-java,Rx Java,接下来的一个重要变化是,null不再被接受为流元素,即以下代码将抛出异常:Observable.just(null) 老实说,我对这一变化的感受是复杂的,我的一部分人理解这将强制执行干净的API,但我可以看到许多可能出现问题的用例 例如,在我的应用程序中,我有一个内存缓存: @Nullable CacheItem findCacheItem(long id); 缓存中可能不存在CacheItem,因此方法可能返回空值 与Rx*一起使用的方式如下: Observable<CacheItem
null
不再被接受为流元素,即以下代码将抛出异常:Observable.just(null)
老实说,我对这一变化的感受是复杂的,我的一部分人理解这将强制执行干净的API,但我可以看到许多可能出现问题的用例
例如,在我的应用程序中,我有一个内存缓存:
@Nullable CacheItem findCacheItem(long id);
缓存中可能不存在CacheItem,因此方法可能返回空值
与Rx*一起使用的方式如下:
Observable<CacheItem> getStream(final long id) {
return Observable.fromCallable(new Callable<CacheItem>() {
@Override public CacheItem call() throws Exception {
return findCacheItem(id);
}
});
}
使用RxJava2,我不再被允许在流中发布null
,因此我要么需要将我的CacheItem包装到其他类中,让流生成该包装器,要么进行相当大的架构更改
在我看来,将每个流元素包装成可为空的对应元素并不合适
我是不是错过了一些基本的东西
看起来像我这样的情况很流行,所以我很好奇,在RxJava2中有了新的“非空”策略后,解决这个问题的推荐策略是什么
编辑
请参见中的后续对话。好吧,有几种方法可以表达您的需求 一种选择是使用
可观察的:
可观察的getStream(最终长id){
返回可观察。延迟(()->{
返回可观察的.just(可选的.ofNullable(findCacheItem(id));
});
}
公共静态变压器去优化(){
返回src->
src.flatMap(item->item.isPresent()
?可观察的.just(item.get())
:可见。空();
}
然后使用.compose(deoptionalize())
从可选的可观察对象映射到非可选的可观察对象。作为另一种解决方案,您可以添加静态实例CacheItem.NULL,并在没有缓存数据时将其返回给订阅服务器
Single
.concat(loadFromMemory(), loadFromDb(), loadFromServer())
.takeFirst { it != CachedItem.NULL }
.subscribe(
您可以使用来处理RxJava2中的空值
根据您的情况,您可以:
Observable<CacheItem> getStream(final long id) {
return RxNullable.fromCallable(() -> findCacheItem(id))
.onNullDrop()
.observable();
}
Observable.just(user)
.map(user -> user.getName())
.map(name -> convertNameToId(name))
.flatMap(id -> getStream(id).onNullRun(() -> showPrompt()))
.map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
.subscribe(userInfo -> showUserInfo());
NullableObservable<CacheItem> getStream(final long id) {
return RxNullable.fromCallable(() -> findCacheItem(id)).observable();
}
可能的解决方案是使用Maybe.switchIfEmpty
例如:
public static <T> Maybe<T> maybeOfNullable(T value) {
return value == null ? Maybe.empty() : Maybe.just(value);
}
maybeOfNullable(user)
.map(user -> user.getName())
.map(name -> convertNameToId(name))
.flatMap(id -> getStream(id))
.map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
// perform another action in case there are no any non null item emitted
.switchIfEmpty(Maybe.fromAction(() -> showPrompt()))
.subscribe(userInfo -> showUserInfo());
公共静态可能不可用(T值){
返回值==null?Maybe.empty():Maybe.just(value);
}
可能不可用(用户)
.map(用户->用户.getName())
.map(名称->转换名称ID(名称))
.flatMap(id->getStream(id))
.map(cacheItem->getUserInfoFromCacheItem(cacheItem))
//如果没有发出任何非空项,则执行另一个操作
.switchIfEmpty(可能是.fromAction(()->showPrompt()))
.subscribe(userInfo->showUserInfo());
Observable.just(user)
.map(user -> user.getName())
.map(name -> convertNameToId(name))
.flatMap(id -> getStream(id).onNullRun(() -> showPrompt()))
.map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
.subscribe(userInfo -> showUserInfo());
NullableObservable<CacheItem> getStream(final long id) {
return RxNullable.fromCallable(() -> findCacheItem(id)).observable();
}
public static <T> Maybe<T> maybeOfNullable(T value) {
return value == null ? Maybe.empty() : Maybe.just(value);
}
maybeOfNullable(user)
.map(user -> user.getName())
.map(name -> convertNameToId(name))
.flatMap(id -> getStream(id))
.map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
// perform another action in case there are no any non null item emitted
.switchIfEmpty(Maybe.fromAction(() -> showPrompt()))
.subscribe(userInfo -> showUserInfo());