在 RxJava2 中处理 null [英] Handling null in RxJava2

查看:38
本文介绍了在 RxJava2 中处理 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着即将发布的 RxJava2 发布,其中一项重要变化是 null 不再被接受为流元素,即以下代码将抛出异常:Observable.just(null)

With the upcoming RxJava2 release one of the important changes is that null is no longer accepted as a stream element, i.e. following code will throw an exception: Observable.just(null)

老实说,我对这一变化的感觉很复杂,我的一部分理解它会强制执行干净的 API,但我可以看到许多用例,这可能是一个问题.

Honestly, I have mixed feelings about this change and part of me understands that it will enforce clean APIs, but I can see a number of use cases when this might be a problem.

例如,在我的应用程序中,我有一个内存缓存:

For instance, in my app I have an in-memory cache:

@Nullable CacheItem findCacheItem(long id);

CacheItem 可能不存在于缓存中,因此方法可能返回空值.

CacheItem might not be present in cache, so method might return null value.

它与 Rx* 一起使用的方式如下:

The way it is used with Rx* - is as following:

Observable<CacheItem> getStream(final long id) {
    return Observable.fromCallable(new Callable<CacheItem>() {
        @Override public CacheItem call() throws Exception {
            return findCacheItem(id);
        }
    });
}

因此,使用这种方法,我可能会在我的流中获得 null,这是完全有效的情况,因此在接收端正确处理 - 假设如果缓存中不存在项目,UI 会更改其状态:

So with this approach, I might get null in my stream which is totally valid situation, so it is handled properly on receiving side - let's say UI changes its state if item is not present in cache:

Observable.just(user)
          .map(user -> user.getName())
          .map(name -> convertNameToId(name))
          .flatMap(id -> getStream(id))
          .map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
          .subscribe(
              userInfo -> {
                  if(userInfo != null) showUserInfo();
                  else showPrompt();
              }
          );

使用 RxJava2,我不再允许在流中发布 null,所以我要么需要将我的 CacheItem 包装到其他某个类中并让我的流生成该包装器,要么进行相当大的架构更改.

With RxJava2 I am no longer allowed to post null down the stream, so I either need to wrap my CacheItem into some other class and make my stream produce that wrapper instead or make quite big architectural changes.

将每个单独的流元素包装成可空的对应元素在我看来并不合适.

Wrapping every single stream element into nullable counterpart doesn't look right to me.

我在这里遗漏了一些基本的东西吗?

Am I missing something fundamental here?

看起来像我这样的情况很流行,所以我很好奇在 RxJava2 中考虑到新的no null"策略来解决这个问题的推荐策略是什么?

It seems like the situation like mine is quite popular, so Im curious what is the recommended strategy to tackle this problem given new "no null" policy in RxJava2?

编辑请参阅 RxJava GitHub repo

推荐答案

嗯,有几种方法可以表示您想要的内容.

Well, there are several ways to represent what you want.

一种选择是使用Observable>:

Observable<Optional<CacheItem>> getStream(final long id) {
  return Observable.defer(() -> {
    return Observable.just(Optional.ofNullable(findCacheItem(id)));
  });
}

public static <T> Transformer<Optional<T>, T> deoptionalize() {
  return src -> 
      src.flatMap(item -> item.isPresent()
             ? Observable.just(item.get())
             : Observable.empty();
}

然后使用 .compose(deoptionalize()) 将可选的 Observable 映射到非可选的 Observable.

You then use .compose(deoptionalize()) to map from the optional to the non-optional Observable.

这篇关于在 RxJava2 中处理 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆