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
);