简体   繁体   中英

RxJava: How can I wrap a multi-step operation, returning the step complete to observers?

Lets say I have a login and user data method, representing HTTP calls:

Single<LoginResponse> login();
Single<UserData> userData();

I need to call login() then userData() . If both succeed, the user is logged in.

I know how to wrap them up in a eg Completable :

Completable performLogin() {
    login().doOnSuccess(this::storeLoginResponse)
        .flatMap(userData())
        .doOnSuccess(this::storeUserData)
        .doOnError(this::wipeLoginData)
        .toCompletable();
}

So the UI then says

showLoading();
performLogin().subscribe(() -> {
    stopLoading();
    onLoginSuccess();
}, error -> {
    stopLoading();
    onLoginFailure();
});

What if the UI needs to show which stage of the loading is happening? As in, when the login() call completes and the userData() call starts it will change the UI?

What I thought of is something like

Observable<LoginStage> performLogin() {
    return Observable.create(emitter -> {
        login.doOnSuccess(response -> {
            storeLoginResponse(response)
            emitter.onNext(LOGIN_COMPLETE)
        }).flatMap(userData())
        .subscribe(userData -> {
            storeUserData(userData);
            emitter.onNext(USER_DATA_COMPLETE)
            emitter.onComplete();
        }, error -> {
            wipeLoginData();
            emitter.onError(error);
        });
    });
}

But it feels like there's a nicer or more Rx-y way to do it.

You can use hot observables and chain one observable to another Subject and pass all items form one emission to another if you need it.

@Test
public void chainObservablesWithSubject() throws InterruptedException {
    Observable<Long> observable = Observable.from(Arrays.asList(1l, 2l, 3l, 4l));
    Subject<Long, Long> chainObservable = ReplaySubject.create(1);
    observable.subscribe(chainObservable);
    chainObservable.subscribe(System.out::println, (e) -> System.err.println(e.getMessage()), System.out::println);
}

You can check more examples here https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/connectable/HotObservable.java

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM