任务取消如何在RxJava中工作?

时间:2014-08-16 21:18:48

标签: java rx-java

我不清楚如何在RXJava中实现任务取消。

我对移植使用Guava' ListenableFuture构建的现有API感兴趣。我的用例如下:

  • 我有一个由Futures.transform()加入的期货序列组成的单一操作
  • 多个订阅者观察操作的最终未来。
  • 每位观察员都可以取消最后的未来,所有观察员都会看到取消事件。
  • 取消最后的未来会导致取消其依赖关系,例如:按顺序1 - > 2 - > 3,取消3会传播到2,依此类推。

RxJava wiki中有关于此的信息非常少;我可以找到的唯一引用取消提及Subscription等同于.NET的Disposable,但据我所知,订阅只能提供取消订阅后续值的功能。序列

我不清楚如何实施"任何订阅者都可以取消"通过这个API的语义。我是以错误的方式思考这个问题吗?

任何意见都会受到赞赏。

1 个答案:

答案 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 cancelStream1cancelStream2等,那么它变得相当简单“取消“finalStream生成的操作:

Observable<FooBar> finalAndCancelableStream = finalStream
    .takeUntil( Observable.merge(cancelStream1, cancelStream2) );

在图表中,this is how takeUntil worksthis is how merge works

用简单的英语,您可以将其读作“finalAndCancelableStream是finalStream,直到cancelStream1或cancelStream2发出事件”。