RxJava:如何包装多步操作,将步骤完成返回给观察者?

时间:2017-12-26 22:08:42

标签: java rx-java2

假设我有一个登录和用户数据方法,代表HTTP调用:

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

我需要致电login()然后userData()。如果两者都成功,则用户已登录。

我知道如何将它们包装在例如Completable

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

然后用户界面说

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

如果UI需要显示正在进行加载的哪个阶段,该怎么办?同样,当login()来电完成且userData()来电启动时,它会改变用户界面吗?

我想到的是像

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);
        });
    });
}

但感觉有更好或更多的Rx-y方式。

1 个答案:

答案 0 :(得分:0)

你可以使用热观察者并将一个观察者链接到另一个主题,并在需要时将所有项目从一个发射传递到另一个。

@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);
}

您可以在https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/connectable/HotObservable.java

查看更多示例