RxJava 发射具有最小延迟的项目

3

我有一个名为UserConfig的配置文件,我希望在启动画面期间下载它。

class UserManager {
    Single<UserConfig> loadConfig()
}

下载完UserConfig后,用户将被重定向到下一个屏幕。我会做类似以下的事情:

@Override
public void onResume(boolean isNewView) {
    subscriptions.add(
            userManager.loadConfig().subscribe(config -> {
                applyConfig(config);
                launchActivity(HomeActivity.class);
            }, error -> {
                //some error handling
            })
    );
}

然而,我希望至少展示1秒钟的启动画面。如果加载时间小于1秒,请添加额外的延迟。

我认为.delay().delaySubscription()在我的情况下不起作用,因为它们会延迟每个请求(无论是否短于1秒)。

2个回答

3

尝试使用Zip运算符。

返回一个Single,该Single发出应用于另外两个Single发出的两个项目的指定组合器函数的结果。

您可以执行类似以下操作:

Single
    .zip(
        Single.timer(1, TimeUnit.SECONDS), 
        userManager.loadConfig(),
        (time, config) -> config
    )
    .subscribe(
        config -> {
            applyConfig(config);
            launchActivity(HomeActivity.class);
        }, error -> {
            //some error handling
        }
     );

谢谢,我没有考虑使用定时器压缩并忽略其结果。 - undefined

1

我使用Kotlin扩展函数对Single类型进行了解决方案。这个延迟操作与错误类似。

/**
 * sets the minimum delay on the success or error
 */
fun <T> Single<T>.minDelay(time: Long, unit: TimeUnit, scheduler: Scheduler = Schedulers.computation()): Single<T> {
    val timeStart = scheduler.now(TimeUnit.MILLISECONDS)
    val delayInMillis = TimeUnit.MILLISECONDS.convert(time, unit)
    return Single.zip(
        Single.timer(time, unit, scheduler),
        this.onErrorResumeNext { error: Throwable ->
            val afterError = scheduler.now(TimeUnit.MILLISECONDS)
            val millisPassed = afterError - timeStart

            val needWaitDelay = delayInMillis - millisPassed
            if (needWaitDelay > 0)
                Single.error<T>(error)
                    .delay(needWaitDelay, TimeUnit.MILLISECONDS, scheduler, true)
            else
                Single.error<T>(error)
        },
        BiFunction { _, t2 -> t2 }
    )
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接