RxJava fromCallable和取消订阅

时间:2018-08-26 21:24:02

标签: java rx-java

我有以下代码(RxJava 1.3.8):

Scheduler scheduler = Schedulers.from(Executors.newSingleThreadExecutor());

Subscription subscription1 = Completable.fromCallable(() -> {
  Thread.sleep(1000);
  System.out.println("first Callable executed");
  return 0;
})
    .subscribeOn(scheduler)
    .subscribe();

Subscription subscription2 = Completable.fromCallable(() -> {
  Thread.sleep(1000);
  System.out.println("second Callable executed");
  return 0;
})
    .subscribeOn(scheduler)
    .subscribe();

CompositeSubscription subscriptions = new CompositeSubscription();
subscriptions.addAll(subscription1, subscription2);
subscriptions.clear();

输出:

  

已执行第一个Callable

     

第二次可调用已执行

问题是-为什么第二个Callable被执行?在运行之前,我希望如果取消订阅,则该订阅将被检查并取消执行。

1 个答案:

答案 0 :(得分:2)

仅在发出值之前检查订阅,但是无论如何,它似乎都会触发可调用对象。

public static Completable fromCallable(final Callable<?> callable) {
    requireNonNull(callable);
    return create(new OnSubscribe() {
        @Override
        public void call(rx.CompletableSubscriber s) {
            BooleanSubscription bs = new BooleanSubscription();
            s.onSubscribe(bs);
            try {
                // calls the callable regardless
                callable.call();
            } catch (Throwable e) {
                if (!bs.isUnsubscribed()) {
                    s.onError(e);
                }
                return;
            }
            // the emission of the complete is guarded
            if (!bs.isUnsubscribed()) {
                s.onCompleted();
            }
        }
    });
}

因此,如果我们要按如下所示修改您的代码,请向每个代码中添加一个doOnComplete

Scheduler scheduler = Schedulers.from(Executors.newSingleThreadExecutor());

Subscription subscription1 = Completable.fromCallable(() -> {
  Thread.sleep(1000);
  System.out.println("first Callable executed");
  return 0;
})
    .doOnComplete(() -> System.out.println("first Completable complete"))
    .subscribeOn(scheduler)
    .subscribe();

Subscription subscription2 = Completable.fromCallable(() -> {
  Thread.sleep(1000);
  System.out.println("second Callable executed");
  return 0;
})
    .doOnComplete(() -> System.out.println("second Completable complete"))
    .subscribeOn(scheduler)
    .subscribe();

CompositeSubscription subscriptions = new CompositeSubscription();
subscriptions.addAll(subscription1, subscription2);
subscriptions.clear();

我们得到:

first Callable executed
second Callable executed

如果我们不清除订阅,则会看到额外的输出,即

first Callable executed
first Completable complete
second Callable executed
second Completable complete