You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RxJava中延迟onSuccess与onError方法的执行?

在RxJava中同时延迟onSuccess与onError的实现方案

要实现启动页至少显示8秒,无论请求成功或失败都满足该时间要求,可以通过RxJava的materialize()和dematerialize()操作符结合自定义延迟逻辑来实现,同时覆盖成功和错误场景。

核心思路

将Observable的所有事件(包括onNext、onError)包装为Notification对象,统一计算延迟时间:

  1. 记录请求订阅时的时间戳
  2. 当事件产生时,计算已耗时与8秒的差值
  3. 若已耗时不足8秒,延迟剩余时长后发射事件;若已超过8秒,立即发射
  4. 最后将包装的事件还原为原始回调

实现代码

首先定义一个可复用的ObservableTransformer:

import io.reactivex.Observable;
import io.reactivex.ObservableTransformer;
import io.reactivex.Scheduler;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.notifications.Notification;
import java.util.concurrent.TimeUnit;

public static <T> ObservableTransformer<T, T> delayAtLeast(long minimumDuration, TimeUnit unit) {
    return upstream -> {
        // 使用请求所在的调度器获取时间,避免系统时间变动影响计算
        Scheduler scheduler = Schedulers.io();
        long startTime = scheduler.now(TimeUnit.MILLISECONDS);
        
        return upstream
                // 将所有事件包装为Notification对象,错误事件不会中断流
                .materialize()
                // 根据已耗时计算延迟时长
                .delay(notification -> {
                    long elapsedTime = scheduler.now(TimeUnit.MILLISECONDS) - startTime;
                    long requiredDelay = unit.toMillis(minimumDuration) - elapsedTime;
                    // 确保延迟时间不小于0
                    return Observable.timer(Math.max(requiredDelay, 0), TimeUnit.MILLISECONDS, scheduler);
                })
                // 还原为原始事件,恢复正常的onSuccess/onError回调
                .dematerialize();
    };
}

在项目中使用

将该Transformer应用到你的Retrofit请求Observable上:

apiService.fetchData()
        .compose(delayAtLeast(8, TimeUnit.SECONDS))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
                data -> {
                    // 数据加载成功,导航至HomeFragment
                    navigateToHomeFragment();
                },
                error -> {
                    // 加载失败,处理错误逻辑(如提示用户、重试等)
                    handleLoadingError(error);
                }
        );

关键细节说明

  • materialize():这是实现同时处理成功和错误事件的核心,它把onError事件包装成一个Notification对象,让错误不会中断整个流,从而能被后续的delay操作处理。
  • 时间计算:使用调度器的now()方法而非系统时间,避免系统时间被手动调整导致的延迟计算错误,保证时间逻辑的准确性。
  • 线程一致性:延迟操作使用与请求相同的调度器(Schedulers.io()),避免线程切换带来的额外开销。

内容的提问来源于stack exchange,提问作者Taha Sami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:21:13