onErrorResumeNext未将控制权传递至发布者的问题排查
问题分析与修复方案
你的问题主要出在两个核心点:onErrorResumeNext的lambda遗漏返回值,以及**map操作符的错误使用**,这直接导致远程数据源的调用逻辑没有被正确传递给错误恢复操作符,自然不会触发远程请求。
1. 第一个问题:onErrorResumeNext的lambda未返回流
看你的错误恢复代码:
.onErrorResumeNext(throwable -> { remoteDataSource.loadPhoto(postId) .map(photoOptional -> { if (photoOptional.isPresent()) { return photoOptional.get(); } else { return Flowable.empty(); } }); })
这里的lambda表达式没有写return语句,默认返回void,但onErrorResumeNext要求传入一个能返回Publisher<? extends Photo>的函数。因为没有返回远程数据源的Flowable,当本地触发错误时,错误恢复操作符根本没有可切换的流,远程请求自然不会执行。
2. 第二个问题:map不能返回Flowable类型
在远程数据源的处理中,你试图在else分支返回Flowable.empty(),但map操作符的作用是将上游的单个元素转换为另一个单个元素,而非另一个流。这里应该用flatMap,它允许你将元素转换为一个流,并将这个流的元素合并到主序列中。
修复后的完整代码
@Override public Flowable<Photo> loadPhoto(String postId) { return localDataSource.loadPhoto(postId) .onErrorResumeNext(throwable -> { // 必须return远程数据源的Flowable,让onErrorResumeNext拿到切换目标 return remoteDataSource.loadPhoto(postId) .flatMap(photoOptional -> { if (photoOptional.isPresent()) { return Flowable.just(photoOptional.get()); } else { return Flowable.empty(); } }); }) .subscribeOn(schedulerProvider.io()) .observeOn(schedulerProvider.mainThread()); }
额外优化建议:本地数据源的RxJava规范写法
你手动实现Publisher的方式略显繁琐,推荐用Flowable.defer来简化,同时避免手动管理Subscriber的生命周期:
@Override public Flowable<Photo> loadPhoto(final String postId) { return Flowable.defer(() -> { Integer id = Integer.valueOf(postId); Feed feed = feedDao.getFeed(id); if (feed != null) { return Flowable.just(mapper.transform(feed)); } Post post = postDao.getPost(id); if (post != null) { return Flowable.just(postToPhotoMapper.transform(post)); } Timber.i("MESA STO ERROR"); return Flowable.error(new Throwable("boo")); }); }
内容的提问来源于stack exchange,提问作者Mes
相关产品推荐
相关产品推荐

