在 RxJava 里,“优雅降级”通常指:当主数据流(或某个依赖调用)失败 / 超时 / 不可用 时,不直接抛错崩溃,而是切换到兜底逻辑(默认值、缓存、备用接口、本地数据等),保证业务可用。
下面按常见场景 + 推荐写法来说明。
适合:接口失败但可以用默认值继续
api.getUser()
.onErrorReturn(throwable -> User.EMPTY)
.subscribe(user -> {
// 永远能拿到 user
});
✅ 优点:简单、无额外流
❌ 缺点:只能返回单个值
适合:主接口失败 → 用缓存 / 本地数据 / 备用接口
api.getUser()
.onErrorResumeWith(cache.getUser())
.subscribe(user -> {
// 主失败 → 走缓存
});
或 Java 风格:
api.getUser()
.onErrorResumeNext(throwable -> cache.getUser());
✅ 这是最标准的降级方式
适合:不同错误不同兜底
api.getUser()
.onErrorResumeNext(throwable -> {
if (throwable instanceof TimeoutException) {
return cache.getUser();
}
return Single.just(User.EMPTY);
});
api.getUser()
.timeout(2, TimeUnit.SECONDS)
.onErrorResumeNext(cache.getUser())
.subscribe();
❗ 注意:
timeout 抛出的是 TimeoutException,要在 onErrorResumeNext 里接住
Observable<User> source;
if (network.isAvailable()) {
source = api.getUser();
} else {
source = cache.getUser();
}
source.subscribe();
或者用 Rx 写法:
Observable.just(network.isAvailable())
.flatMap(available ->
available ? api.getUser() : cache.getUser()
);
api.getUser()
.retryWhen(errors ->
errors.zipWith(Observable.range(1, 3), (e, i) -> i)
.flatMap(retryCount ->
Observable.timer(1, TimeUnit.SECONDS)
)
)
.onErrorResumeNext(cache.getUser())
.subscribe();
逻辑:
Observable.mergeDelayError(
api.getUser(),
cache.getUser()
).firstElement().subscribe();
或:
Single.zip(
api.getUser().onErrorResumeNext(Single.never()),
cache.getUser(),
(apiUser, cacheUser) -> apiUser != null ? apiUser : cacheUser
);
api.getUser()
.subscribeOn(Schedulers.io())
.timeout(3, TimeUnit.SECONDS)
.onErrorResumeNext(cache.getUser())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
user -> showUser(user),
e -> showError()
);
❌ 不要吞异常而不记录
.onErrorReturn(e -> null) // 易出 NPE
✅ 建议:
❌ 不要在 onError 里做业务跳转
onErrorResumeNextRxJava 优雅降级 = onErrorResumeNext / onErrorReturn + timeout + 备用数据源
如果你愿意,可以告诉我:
我可以直接帮你写一套可复用降级模板。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。