RxJava的懒加载,慎重使用自定义操作符,优先考虑内置操作符

我越来越喜欢把RxJava的defer()操作符作为一个工具来使用,以确保Observable代码在被订阅后才执行(而不是创建后立即执行)。我之前写过一些有关defer()的代码,但是,现在我想做更详细的描述。

假设,有个数据类:

public class SomeType {  
private String value;

public void setValue(String value) {
  this.value = value;
}

public Observable<String> valueObservable() {
  return Observable.just(value);
}
}

这段代码在运行后会打印出什么呢?

SomeType instance = new SomeType();  
Observable<String> value = instance.valueObservable();  
instance.setValue("Some Value");  
value.subscribe(System.out::println);

如果你认为会打印出“Some Value”,那就错了。而实际打印结果是“null”。因为在调用Observable.just()的时候,value已经初始化了。

just(),from()这类能够创建Observable的操作符(译者注:创建Observable的操作符)在创建之初,就已经存储了对象的值,而不被订阅的时候。这种情况,显然不是预期表现,我想要的valueObservable()是无论什么时候请求,都能够表现为当前值。

自助

一个解决办法就是使用Observable.create(),因为它允许为每个订阅者精确控制事件的发送。

public Observable valueObservable() {
return Observable.create(new Observable.OnSubscribe() {
@Override public void call(Subscriber

简单粗暴

这里有一种不需要自定义操作符的实现方式:

public Observable<String> valueObservable() {
  return Observable.defer(new Func0<Observable<String>>() {
    @Override public Observable<String> call() {
      return Observable.just(value);
    }
  });
}

我所做的就是用defer()操作符封装原始代码,但现在的表现正是我想要的。defer()中的代码直到被订阅才会执行。我们只需要在请求数据的时候调用Observable.just()就哦了。

我更喜欢这个解决方案的原因:

比Observable.create()更简单,不再需要手动调用onCompleted()。
使用内置操作符,这种方式(可能)更得到官方的肯定。
使用defer()操作符的唯一缺点就是,每次订阅都会创建一个新的Observable对象。create()操作符则为每一个订阅者都使用同一个函数,所以,后者效率更高。一如既往地,如果有必要可以亲测性能或者尝试优化。

深入

上面代码仅仅是为讲解所用,但是,切换到实际生产中,我们需要用BehaviorSubject替换所有代码。让我们来看一些更复杂的东西。

假设需要一个方法,首先将数据写进磁盘,然后再作为结果返回。这是一种用defer()操作符的实现:

public Observable<SomeType> createSomeType(final String value) {
  return Observable.defer(new Func0<Observable<SomeType>>() {
    @Override public Observable<SomeType> call() {

      SomeType someType = new SomeType();
      someType.setValue(value);

      try {
        db.writeToDisk(someType);
      } catch (IOException e) {
        return Observable.error(e);
      }

      return Observable.just(someType);
    }
  });
}

这个例子稍微复杂一些,将数据写进磁盘的同时如果抛出异常并捕获,则立即调用onError,基本的思路是相同的,那就是:在订阅发生之前,不希望执行任何代码。

其实,有很多方式可以解决上面的问题,虽然使用defer()操作符只是其中之一,但是,使用起来真的很方便。

原文链接: Deferring Observable code until subscription in RxJava
原文作者: Dan Lew
译文出自: 小鄧子的简书

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值