【问题标题】:Difference between Observable.defer and Observable.create in java rxjava rx 中 Observable.defer 和 Observable.create 的区别
【发布时间】:2016-03-30 15:55:34
【问题描述】:

有人能解释一下Observabledefercreate 方法之间的区别吗?我不明白什么时候应该使用defer,什么时候应该使用create..

参考:

延迟:http://reactivex.io/documentation/operators/defer.html

创建:http://reactivex.io/documentation/operators/create.html

谢谢

【问题讨论】:

    标签: java reactivex


    【解决方案1】:

    所以区别似乎是:defer 很好,当你有一些东西已经创建/返回了一个 observable,但你不希望它在订阅之前发生。

    create 在您需要手动包装异步进程并创建可观察对象时非常有用。该创建推迟到订阅。

    换一种说法:

    defer 是一个可以延迟组合可观察序列的运算符。

    create 是可观察序列的自定义实现(创建延迟到订阅)。

    因此,如果您有可能使用just 从某些结果/值创建Observable 的情况,或者您有一个返回请求的Observable 的网络API 层,但您不希望该请求开始直到订阅。 defer 非常适合这些场景。

    如果您有一个为请求返回Observable 的网络API 层,但您需要一个Observable 接口,您可以使用createObservable 序列在订阅之前仍然不会创建。如果您希望无论订阅如何都启动该网络调用,那么您将使用不同的机制,例如 Subject,可能会重播。

    【讨论】:

      【解决方案2】:

      create(...) 实际上会立即创建 Observable。

          public final static <T> Observable<T> create(OnSubscribe<T> f) {
              return new Observable<T>(hook.onCreate(f));
          }
      

      defer(...) 接受返回 Observable(Subject, etc...) 的 Factory 函数,用 OnSubscribeDefer 包装它并仅在订阅者订阅时创建 Observable,为每个订阅者创建新的 Observable。

      public final static <T> Observable<T> defer(Func0<Observable<T>> observableFactory) {
          return create(new OnSubscribeDefer<T>(observableFactory));
      }
      

      查看更多详情here

      【讨论】:

      • create(...) 实际上会立即创建 Observable。 似乎直接与您链接到的其他答案和 Dan 的帖子相矛盾。
      【解决方案3】:

      通过示例的方式,对上面已经非常好的答案的另一种看法。

      假设您有一个基于其内部状态返回 Observable 的类(用类似 Javascript 的伪语言编写,但适用于所有 ReactiveX 实现)

      class DownloadManager {
      
        var uuid = nil  // this only gets set during runtime...say when a user performs a certain action
      
        // fetches some data from the server.
        func get() -> Observable<Data> {
          if uuid == nil {
            return .error(new DownloadUuidEmptyError())
          }
       
          return network.download(uuid, ...) // do something with the non nil uuid
        }
      }
      

      这样写,方法可能被调用,并且 observable 在它实际被评估之前被传递,并且 uuid 可能在方法调用时不存在,但在订阅 Observable 时存在,从而产生错误.

      let observable = manager.get()
      
      // ... at some point, uuid is assigned to
      // then we subscribe to our observable ...
      
      observable.subscribe(...).disposedBy(bag) // errors!
      

      在这种情况下,延迟可以派上用场,以确保在订阅时间之前不会进行评估(例如 uuid)。

        // fetches some data from the server.
        func get() -> Observable<Data> {
          return Observable.defer {
            if uuid == nil {
              return .error(new DownloadUuidEmptyError())
            }
      
            return network.download(uuid, ...) // do something with the non nil uuid
          }
        }
      

      现在,上面的示例将不再出错。也许更大的目标是确保您的代码永远不会达到这种状态,但有时它并不实用。这种模式对我来说很方便。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-13
        • 1970-01-01
        • 1970-01-01
        • 2015-05-03
        相关资源
        最近更新 更多