dev.farmer
dev.farmer

Reputation: 2809

RxJava what's difference Observable.just vs Observable.fromCallable?

I have a question about the difference between Observable.just and Observable.fromCallable.

I have a "service" class like this:

class Service {
    var cachedToken: String = ""
        get() {
            if (needToRefreshToken()) {
                refresh()    // Can throw Exception!!!
            }

            return token
        }
}

And below code is calling upper code like:

Observable.just(service.cachedToken)
    .subscribeOn(ioScheduler)
    .observeOn(uiScheduler)
    .subscribe({ isSuccess ->
        view.showSomething()
    }, {
        view.showError()    // this code is never called!!!
    })

I expected that "view.showError()" method be called when some exception occurs during the "refresh()" token.

But it doesn't.

So I changed the Observable.just => Observable.fromCallable like below:

Observable.fromCallable{ service.cachedToken }
    .subscribeOn(ioScheduler)
    .observeOn(uiScheduler)
    .subscribe({ isSuccess ->
        view.showSomething()
    }, {
        view.showError()
    })

And then it works fine.

In normal case, both codes (just and fromCallable) works fine. "view.showSomething()" is called correctly. But the only exceptional case, they work differently

What difference???

Upvotes: 0

Views: 1123

Answers (3)

Alexey Romanov
Alexey Romanov

Reputation: 170815

The behavior of just isn't special to RxJava. Arguments are always evaluated before method is called, so

Observable.just(service.cachedToken)...

is the same as

val x = service.cachedToken
Observable.just(x)...

So it only calls cachedToken's get once. If get throws an exception, Observable.just call is never reached in the first place, so you still won't get view.showError().

Upvotes: 1

Vivart
Vivart

Reputation: 15313

If we compare code of SingleJust and SingleFromCallable, we can see what is happening here.

SinbleJust

@Override
protected void subscribeActual(SingleObserver<? super T> observer) {
    observer.onSubscribe(Disposables.disposed());
    observer.onSuccess(value);
}

SingleFromCallable

@Override
protected void subscribeActual(SingleObserver<? super T> observer) {
    Disposable d = Disposables.empty();
    observer.onSubscribe(d);

    if (d.isDisposed()) {
        return;
    }
    T value;

    try {
        value = ObjectHelper.requireNonNull(callable.call(), "The callable returned a null value");
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        if (!d.isDisposed()) {
            observer.onError(ex);
        } else {
            RxJavaPlugins.onError(ex);
        }
        return;
    }

    if (!d.isDisposed()) {
        observer.onSuccess(value);
    }
}

Upvotes: 0

Sasi Kumar
Sasi Kumar

Reputation: 13348

From the documents

Observable.just

Returns an Observable that ,signals the given (constant reference) item and then completes.

Observable.fromCallable

Returns an Observable that, when an observer subscribes to it, invokes a function you specify and then emits the value returned from that function.

Upvotes: 1

Related Questions