如果" source"如何不为长期运行的任务提供结果?可观察的变化

时间:2018-04-09 16:19:38

标签: rx-java rx-java2

我通过填充一些观察者来触发长时间运行的CPU密集型任务,而且我无法确定我是否正确设置。

理想情况下,我的要求是:

  • 填充所有3个BehaviorSubjects时触发任务(然后每次更改其中任何一个时)
  • 一次只运行一次计算
  • 不要提供过时"过时的计算结果"由于源触发器改变

我目前的解决方案就是这个,但我不确定这是否是最好的方法。特别是"版本"变量似乎错了。此外,在我的链中指定observeOn似乎是错误的,但我知道这是使用BehaviorSubject的副作用。

    final AtomicInteger version = new AtomicInteger(0);
    return Observable.combineLatest(
                mBehaviorSubjectArg1,
                mBehaviorSubjectArg2,
                mBehaviorSubjectArg3,
                (arg1, arg2, arg3) -> new Arguments(version.incrementAndGet(), arg1, arg2, arg3)
            )
            // Only keep the latest combination so when observeOn pulls we don't run interim data points
            .toFlowable(BackpressureStrategy.LATEST)
            // Only buffer 1 so we don't ask for additional arguments until we have completed the last computation. 
            .observeOn(Schedulers.computation(), false, 1)
            .map(args -> new Pair<>(args, mCalculator.run(args)))
            .filter(pair -> pair.first.version == version.get())
            .map(pair -> pair.second);

1 个答案:

答案 0 :(得分:1)

这似乎是switchMap运算符可以工作的完美示例。如果您可以更改mCalculator.run(args)以返回Observable(如果使用Observable.createObservableEmitter.setCancellable可能允许取消),则以下代码将起作用:

return Observable.combineLatest(
            mBehaviorSubjectArg1,
            mBehaviorSubjectArg2,
            mBehaviorSubjectArg3,
            (arg1, arg2, arg3) -> new Arguments(arg1, arg2, arg3)
        ).switchMap((args) -> mCalculator.run(args).subscribeOn(Schedulers.computation()))

switchMap将确保只有最新的Arguments实例将同时运行,如果combineLatest发出新实例,则取消Observable。 subscribeOn中的switchMap用于确保mCalculator.run

中的错误不会导致死锁