Rx java RxJava Observable.dounsubscribe()与Subscriber.add()的比较

Rx java RxJava Observable.dounsubscribe()与Subscriber.add()的比较,rx-java,Rx Java,我有时不得不在我的观察对象中做一些清理任务(例如关闭打开的文件),我想知道什么是最好的方法。 到目前为止,我已经看到了两个,但我很难理解它们的区别:你能解释一下它们的区别吗?如果有更好的方法来实现这一点的话 (一) //MyObject将负责调用onNext()、onError()和onCompleted() //在订阅服务器上。 最终MyObject o=新的MyObject(); Observable obs=Observable.create(newobservable.OnSubscri

我有时不得不在我的观察对象中做一些清理任务(例如关闭打开的文件),我想知道什么是最好的方法。 到目前为止,我已经看到了两个,但我很难理解它们的区别:你能解释一下它们的区别吗?如果有更好的方法来实现这一点的话

(一)

//MyObject将负责调用onNext()、onError()和onCompleted()
//在订阅服务器上。
最终MyObject o=新的MyObject();
Observable obs=Observable.create(newobservable.OnSubscribe()){
@凌驾

public void call(Subscriber如果不在Subscriber.onNext的下游添加任何值,那么使用Observable.create有什么意义

第一个是一个巨大的否定,因为你正在对一个已经关闭的对象进行副作用。如果你同时从两个不同的线程订阅创建的observable,会发生什么

第二个看起来更好,因为您添加了subscriber.add,如果已释放订阅,它将调用o.stop()。唯一缺少的是调用onNext,即值向下游移动


有一个用于从资源创建可观察对象的操作符,称为“使用”。请查看

如果您没有将任何值放在subscriber.onNext的下游,那么使用Observable.create有什么意义

第一个是一个巨大的否定,因为你正在对一个已经关闭的对象进行副作用。如果你同时从两个不同的线程订阅创建的observable,会发生什么

第二个看起来更好,因为您添加了subscriber.add,如果已释放订阅,它将调用o.stop()。唯一缺少的是调用onNext,即值向下游移动


有一个用于从资源创建可观察对象的操作符,称为“使用”。请看一下来回答您的原始问题,
dounsubscribe
和向
订阅者添加
Subscription
是一样的。事实上,当您调用
dounsubscribe
时,它只是将您的
操作作为
订阅添加到您的
订阅者中。因此,
dounsubscribe>Subscribe
在后台使用第二个示例

dounsubscribe
code:

public class OperatorDoOnUnsubscribe<T> implements Operator<T, T> {
  private final Action0 unsubscribe;

/**
 * Constructs an instance of the operator with the callback that gets invoked when the modified Observable is unsubscribed
 * @param unsubscribe The action that gets invoked when the modified {@link rx.Observable} is unsubscribed
 */
public OperatorDoOnUnsubscribe(Action0 unsubscribe) {
    this.unsubscribe = unsubscribe;
}

@Override
public Subscriber<? super T> call(final Subscriber<? super T> child) {
    child.add(Subscriptions.create(unsubscribe));

    // Pass through since this operator is for notification only, there is
    // no change to the stream whatsoever.
    return Subscribers.wrap(child);
  }
}
公共类运算符doonUnsubscribe运算符{
私人最终行动0取消订阅;
/**
*构造一个带有回调的运算符实例,该回调在取消订阅修改的Observable时被调用
*@param unsubscribe取消订阅修改的{@link rx.Observable}时调用的操作
*/
公共运营商取消订阅(操作0取消订阅){
this.unsubscribe=取消订阅;
}
@凌驾

公共订阅者为了回答您最初的问题,向
订阅者添加
订阅和向
订阅者添加
订阅都是一样的。事实上,当您调用
dounsubscribe
时,它只是将您的
操作作为
订阅添加到您的
订阅者中。因此,
dounsubscribe
在后台使用第二个示例

dounsubscribe
code:

public class OperatorDoOnUnsubscribe<T> implements Operator<T, T> {
  private final Action0 unsubscribe;

/**
 * Constructs an instance of the operator with the callback that gets invoked when the modified Observable is unsubscribed
 * @param unsubscribe The action that gets invoked when the modified {@link rx.Observable} is unsubscribed
 */
public OperatorDoOnUnsubscribe(Action0 unsubscribe) {
    this.unsubscribe = unsubscribe;
}

@Override
public Subscriber<? super T> call(final Subscriber<? super T> child) {
    child.add(Subscriptions.create(unsubscribe));

    // Pass through since this operator is for notification only, there is
    // no change to the stream whatsoever.
    return Subscribers.wrap(child);
  }
}
公共类运算符doonUnsubscribe运算符{
私人最终行动0取消订阅;
/**
*构造一个带有回调的运算符实例,该回调在取消订阅修改的Observable时被调用
*@param unsubscribe取消订阅修改的{@link rx.Observable}时调用的操作
*/
公共运营商取消订阅(操作0取消订阅){
this.unsubscribe=取消订阅;
}
@凌驾

公共订户首先不要使用
Observable.create(OnSubscribe)
,如果你能帮助的话,因为你很容易破坏东西(比如背压或可观察到的合同相关东西)。你应该使用许多静态工厂方法中的一种

除此之外,我建议您不要直接回答您的问题,而是使用
Observable.using
,它的设计目的是明确地在终止或取消订阅时释放资源

例如:

Observable<byte[]> bytes = 
  Observable.using(
    () -> new FileInputStream(file), //resource factory
    is -> Bytes.from(is), // observable factory
    is -> is.close() // close action
  );    

首先,不要使用
Observable.create(OnSubscribe)
,如果你能帮助的话,因为你很容易破坏东西(比如背压或可观察到的合同相关的东西)。你应该使用许多静态工厂方法中的一种

除此之外,我建议您不要直接回答您的问题,而是使用
Observable.using
,它的设计目的是明确地在终止或取消订阅时释放资源

例如:

Observable<byte[]> bytes = 
  Observable.using(
    () -> new FileInputStream(file), //resource factory
    is -> Bytes.from(is), // observable factory
    is -> is.close() // close action
  );    

您提到的两种解决方案中使用哪一种取决于您尝试使用/关闭/处置的资源是否要在多个订阅之间共享

  • 使用订阅服务器。在资源用于生成事件时添加(…)。在这种情况下,您将不希望共享资源

    • 在您的
      MyObject
      示例中就是这种情况。这样做的好处是资源不会暴露在
      Observable.create()
      方法之外,从而使资源免受意外的副作用
  • 当您必须在多个订阅中共享某些内容时,请使用dounsubscribe

    • 例如,如果您想拥有一个计数器,计算可观察对象的使用次数,您可以拥有一个共享计数器,并在
      dounsubscribe
      dounsubscribe
      中不断递增
    • 另一个例子是,如果您想有一个计数器来计算当前对资源开放的连接数,您可以在
      doOnSubscribe
      doOnSubscribe
      中相应地使用递增和递减组合来实现这一点
  • 同样在你的例子中,用o代替
    Observable.using(
      () -> new MyObject(), //resource factory
      myObject -> makeObservable(myObject), // observable factory
      myObject -> myObject.stop() // close action
    );