Robert Lewis
Robert Lewis

Reputation: 1907

Behavior of Single.fromObservable()

The docs for Single.fromObservable() say "If the source Observable has more than one element, an IndexOutOfBoundsException is signaled." But this could never happen if the subscription is disposed immediately after receipt (and re-emission) of the Observable's first element. The Single would have to maintain the subscription until it received either onNext() [causing the IndexOutOfBoundsException], onComplete() [presumably causing it to unsubscribe from the Observable], or onError [presumably passed downstream].

How and when does this operator deal with unsubscribing from the source Observable? Is the documentation correct?

Upvotes: 2

Views: 1352

Answers (1)

akarnokd
akarnokd

Reputation: 70017

Yes, the documentation is correct. If you are in doubt, check the source code:

public void onNext(T t) {
    if (done) {
        return;
    }
    if (value != null) {
        done = true;
        s.dispose();
        actual.onError(new IllegalArgumentException("Sequence contains more than one element!"));
        return;
    }
    value = t;
}

But this could never happen if the subscription is disposed immediately after receipt (and re-emission) of the Observable's first element.

The operator does not dispose after the first emission but only after the second item, which yields the IndexOutOfBoundsException.

After that, the onComplete is responsible for emitting the single item (or a default one):

@Override
public void onComplete() {
    if (done) {
        return;
    }
    done = true;
    T v = value;
    value = null;
    if (v == null) {
        v = defaultValue;
    }

    if (v != null) {
        actual.onSuccess(v);
    } else {
        actual.onError(new NoSuchElementException());
    }
}

Upvotes: 1

Related Questions