RxJava订阅阻止observable

时间:2016-09-16 02:54:38

标签: rx-java

我想实现以下目标:

String result = myObservable.toBlocking().first();

即。它就像一个常规的函数调用。然而,这种情况从未发生过,因为您需要订阅它,我不知道该怎么做。如果我订阅它,结果将在另一个范围内,并且代码非常难看,因为我只能获得结果,就像它的常规observable一样,所以没有必要把它变成一个阻塞的observable。

1 个答案:

答案 0 :(得分:5)

它实际上可以按你的需要工作:

    Observable<String> myObservable = Observable.just("firstValue", "secondValue");
    String result = myObservable.toBlocking().first();
    System.out.println(result); // ---> "firstValue"

在幕后,致电BlockingObservable.first()为您订阅:

private T blockForSingle(final Observable<? extends T> observable) {
    final AtomicReference<T> returnItem = new AtomicReference<T>();
    final AtomicReference<Throwable> returnException = new AtomicReference<Throwable>();
    final CountDownLatch latch = new CountDownLatch(1);

    @SuppressWarnings("unchecked")
    Subscription subscription = ((Observable<T>)observable).subscribe(new Subscriber<T>() {
        @Override
        public void onCompleted() {
            latch.countDown();
        }

        @Override
        public void onError(final Throwable e) {
            returnException.set(e);
            latch.countDown();
        }

        @Override
        public void onNext(final T item) {
            returnItem.set(item);
        }
    });
    BlockingUtils.awaitForComplete(latch, subscription);

    if (returnException.get() != null) {
        Exceptions.propagate(returnException.get());
    }

    return returnItem.get();
}

更新:如果使用BehaviourSubjecttoBlocking()没有任何意义。考虑到它既是Observable又是Observer,所以应该调用myObservable.onNext("value")。如果您通过调用toBlocking()来阻止线程,除非myObservable在调用onNext()的其他线程中可用,否则您将被阻止。

例如,这是'BehaviourSubject:

的正常使用
  // observer will receive the "one", "two" and "three" events, but not "zero"
  BehaviorSubject<Object> subject = BehaviorSubject.create("default");
  subject.onNext("zero");
  subject.onNext("one");
  subject.subscribe(observer);
  subject.onNext("two");
  subject.onNext("three");