我不清楚如何在RXJava中实现任务取消。
我对移植使用Guava' ListenableFuture
构建的现有API感兴趣。我的用例如下:
Futures.transform()
加入的期货序列组成的单一操作1
- > 2
- > 3
,取消3
会传播到2
,依此类推。 RxJava wiki中有关于此的信息非常少;我可以找到的唯一引用取消提及Subscription
等同于.NET的Disposable
,但据我所知,订阅只能提供取消订阅后续值的功能。序列
我不清楚如何实施"任何订阅者都可以取消"通过这个API的语义。我是以错误的方式思考这个问题吗?
任何意见都会受到赞赏。
答案 0 :(得分:16)
了解Cold vs Hot Observables非常重要。如果您的Observable是冷的,那么如果您没有订阅者,他们的操作将不会执行。因此要“取消”,只需确保所有观察者都取消订阅源Observable。
但是,如果只有一个源的观察者取消订阅,并且还有其他观察者仍然订阅了该源,则不会产生“取消”。在这种情况下,您可以使用(但它不是唯一的解决方案)ConnectableObservables。另请参阅this link about Rx.NET。
使用ConnectableObservables的一种实用方法是在任何冷Observable上调用.publish().refCount()
。这样做是创建一个单一的“代理”观察者,它将事件从源传递到实际的观察者。当最后一个实际的Observer取消订阅时,代理Observer取消订阅。
要手动控制ConnectableObservable,只需调用coldSource.publish()
,您将获得ConnectableObservable的实例。然后你可以调用.connect()
,它将返回“代理”观察者的订阅。要手动“取消”源,您只需取消订阅代理Observer的订阅。
对于您的具体问题,您还可以使用.takeUntil()
运算符。
假设您的“最终未来”在RxJava中移植为finalStream
,并假设“取消事件”是Observables cancelStream1
,cancelStream2
等,那么它变得相当简单“取消“finalStream
生成的操作:
Observable<FooBar> finalAndCancelableStream = finalStream
.takeUntil( Observable.merge(cancelStream1, cancelStream2) );
在图表中,this is how takeUntil works和this is how merge works。
用简单的英语,您可以将其读作“finalAndCancelableStream是finalStream,直到cancelStream1或cancelStream2发出事件”。