使用RxJava确保任务至少花费一定的时间

时间:2017-05-11 19:35:47

标签: android rx-java

我正在为Android应用开发一个启动画面,它有一些要求:

  1. 当显示启动画面时,我需要从a获取值 库。一旦获取该值,它将用于启动3 对存储库的不同调用并行。
  2. 启动画面 必须显示至少3秒或只需要获取所有 存储库中的值(如果提取时间超过3) 秒)。
  3. 如果从中获取第一个值时发生错误 然后,可观察链可以终止(一旦3 已经过了几秒钟)
  4. 如果在获取下一个错误时发生任何错误 可观察链不应终止的三个值,即全部 即使一个或多个失败,三个应该运行。
  5. 这是我目前所拥有的:

        Observable<Long> timerObservable = Observable.timer(3, TimeUnit.SECONDS);
    
        cachedObservable = mLoginRepository
                .fetchLoginPreference()
                .onErrorReturn(new Func1<Throwable, LoginPreference>() {
                    @Override
                    public LoginPreference call(Throwable throwable) {
                        return null;
                    }
                })
                .flatMap(new Func1<LoginPreference, Observable<CompositeLPLCPalette>>() {
                    @Override
                    public Observable<CompositeLPLCPalette> call(final LoginPreference loginPreference) {
                        if (loginPreference == null
                                || loginPreference.getActivationCode() == null
                                || loginPreference.getActivationCode().isEmpty()) {
                            Timber.d("login preference was null");
                            return Observable.just(null);
                        }
    
                        final String activationCode = loginPreference.getActivationCode();
    
                        Observable<LoginCapability> loginCapabilityObservable = mLoginRepository
                                .fetchLoginCapability(activationCode, true)
                                .onErrorReturn(new Func1<Throwable, LoginCapability>() {
                                    @Override
                                    public LoginCapability call(Throwable throwable) {
                                        return null;
                                    }
                                });
    
                        Observable<OrgContactInfo> orgContactInfoObservable = mLoginRepository
                                .fetchOrgContactInfo(activationCode, true)
                                .onErrorReturn(new Func1<Throwable, OrgContactInfo>() {
                                    @Override
                                    public OrgContactInfo call(Throwable throwable) {
                                        Timber.d("Error fetching org contact info");
                                        return null;
                                    }
                                });
    
                        Observable<Palette> paletteObservable = mLoginRepository
                                .fetchThemeInformation(activationCode, true)
                                .onErrorReturn(new Func1<Throwable, Palette>() {
                                    @Override
                                    public Palette call(Throwable throwable) {
                                        Timber.d("Error fetching Palette");
                                        return null;
                                    }
                                });
    
                        return Observable.zip(loginCapabilityObservable,
                                paletteObservable,
                                orgContactInfoObservable,
                                new Func3<LoginCapability, Palette, OrgContactInfo, CompositeLPLCPalette>() {
                                    @Override
                                    public CompositeLPLCPalette call(LoginCapability loginCapability, Palette palette, OrgContactInfo orgContactInfo) {
                                        return new CompositeLPLCPalette(loginCapability, loginPreference, palette);
                                    }
                                });
                    }
                })
                .zipWith(timerObservable, new Func2<CompositeLPLCPalette, Long, CompositeLPLCPalette>() {
                    @Override
                    public CompositeLPLCPalette call(CompositeLPLCPalette compositeLPLCPalette, Long aLong) {
                        return compositeLPLCPalette;
                    }
                });
    

    上面的代码有效,但我有几个问题:

    1)我执行3秒最小化的方式是正确的方法吗?看起来有一个延迟操作符和定时器操作符,我不知道应该使用哪个。另外,我是否应该使用链的其余部分压缩计时器操作符?

    2)我是否正确使用onErrorReturn(),如果我的意图是如果observable失败,它应该只返回null而不是订阅者的onError()方法?

    3)在flatMap()运算符中,我正在检查loginPreference是否为null,具有空激活码或空激活码,如果其中任何一个为真,我不想运行其他3个可观察量。在flatMap()运算符之前是否应该使用不同的运算符而不是将此逻辑添加到flatMap()?

1 个答案:

答案 0 :(得分:1)

  1. 是的,这是正确的方法。我建议将flatMap的内容作为一个单独的方法提取出来,并且出于逻辑和维护的原因,将2个zip操作符分开。

  2. 我真的不喜欢在observable中有空值,至少它与RxJava 2不兼容。但是根据要求,逻辑听起来很合理。

  3. 不,你很好。