使用 RxJava 进行嵌套串行网络请求的一种方法
需求
有这样一个列表数据,它包含了商店+订单的信息,获取订单列表时,订单实体中会包含商店的 ID,而列表显示时需要商店的名称和 logo,这时候就需要进行嵌套串行网络请求了。
关键词
flatMap 、缓存 、Retrofit、RxJava
动手
(1)使用 Retrofit 定义网络接口
// RemoteService.java
// 请求订单信息
@POST("/order/v1/order_history")
Single<List<OrderResponse>> queryOrderList(@Body FetchOrderHistoryRequest request);
// 请求商店信息
@POST("/store/v1/store_query")
Single<StoreResponse> queryStore(@Body StoreQueryRequest request);
(2)使用 DataManager 管理数据
// DataManager.java
// 请求订单信息
public Single<List<OrderResponse>> queryOrderList(String status) {
FetchOrderHistoryRequest request = new FetchOrderHistoryRequest();
request.setStatus(status);
return mRemoteService.queryOrderList(request);
}
// 请求商店信息,并缓存 5min,如果不作缓存可能导致多次重复请求同一数据
public static final int DEFAULT_CACHE_TIME_MILLIS = 5 * 60 * 1000; // 5min
public Single<StoreResponse> queryStore(String storeId) {
String storeKey = PrefConstant.getStoreKey(storeId);
String storeJson = mMemberPref.getString(storeKey, null);
Single<StoreResponse> storeSingle;
if (!TextUtils.isEmpty(storeJson)) {
storeSingle = Single.just(Json.fromJson(storeJson, StoreResponse.class));
} else {
StoreQueryRequest request = new StoreQueryRequest();
request.setId(storeId);
storeSingle = mRemoteService.queryStore(request)
.doOnSuccess(storeResponse -> mMemberPref.put(storeKey,
Json.toJson(
storeResponse),
DEFAULT_CACHE_TIME_MILLIS));
}
return storeSingle;
}
注:
mMemberPref是我写的一个使用SharedPreferences进行数据缓存的类,详情查看 Pref.java
(3)多次FlatMap
dataManager.queryOrderList(status)
.flatMapObservable((Function<List<OrderResponse>, ObservableSource<OrderResponse>>) Observable::fromIterable)
.flatMap((Function<OrderResponse, ObservableSource<OrderHolder>>) orderResponse -> {
OrderHolder orderHolder = new OrderHolder();
orderHolder.setOrder(orderResponse);
return dataManager.queryStore(orderResponse.getStoreId())
.flatMapObservable((Function<StoreResponse, ObservableSource<OrderHolder>>) storeResponse -> {
orderHolder.setStore(storeResponse);
return Observable.just(orderHolder);
});
})
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new SingleObserver<List<OrderHolder>>() {
@Override
public void onSubscribe(Disposable d) {
disposable = d;
}
@Override
public void onSuccess(List<OrderHolder> orderHolders) {
if (orderHolders != null && !orderHolders.isEmpty()) {
getMvpView().showOrderList(orderHolders);
} else {
getMvpView().showEmpty();
}
}
@Override
public void onError(Throwable e) {
Timber.e(e);
getMvpView().showError();
}
});
}
说明:
- 第一次
flatMapObservable,将List<OrderResponse>转为ObservableSource<OrderResponse>; - 第二次
flatMap,将OrderResponse转为ObservableSource<OrderHolder>; - 第三次
flatMapObservable,将StoreResponse合并到OrderHolder,再转为ObservableSource<OrderHolder>。
使用 RxJava 进行嵌套串行网络请求的一种方法的更多相关文章
- iOS 串行网络请求。。。待研究
nsurlsession 和 nsurlconnection 能实现吗? 手动实现的关键点在哪里? 我这里说的串行网络请求,指的是第一个网络请求不返回数据,第二个网络请求就不能开始. AFNetwor ...
- Retrofit2+Rxjava+OkHttp的使用和网络请求
Retrofit2+Rxjava+OkHttp的使用和网络请求 https://blog.csdn.net/huandroid/article/details/79883895 加入Rxjava 如果 ...
- Oracle多行记录合并的几种方法
今天正好遇到需要做这个功能,顺手搜了一下网络,把几种方法都列出来,方便以后参考. 1 什么是合并多行字符串(连接字符串)呢,例如: SQL> desc test; Name Type Nulla ...
- 【MySQL】锁——查看当前数据库锁请求的三种方法 20
MySQL提供了查看当前数据库锁请求的三种方法:1. show full processlist命令 观察state和info列 2. show engine innodb status\G ...
- php发送post请求的三种方法示例
本文分享下php发送post请求的三种方法与示例代码,分别使用curl.file_get_content.fsocket来实现post提交数据,大家做个参考. php发送post请求的三种方法,分别使 ...
- php发送get、post请求的6种方法代码示例
本文主要展示了php发送get.post请求的6种方法的代码示例,分别为使用file_get_contents .fopen.fsockopen.curl来发送GET和POST请求,代码如下: 方法1 ...
- sql语句实现行转列的3种方法实例
sql语句实现行转列的3种方法实例 一般在做数据统计的时候会用到行转列,假如要统计学生的成绩,数据库里查询出来的会是这样的,但这并不能达到想要的效果,所以要在查询的时候做一下处理,下面话不多说了,来一 ...
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
今天要说的干货是:以Kotlin,在MVP模式下(OKHttp和 Retrofit+RxJava)网络请求两种实现方式的一个小案例,希望对大家有所帮助,效果图: Retrofit是Square公司开发 ...
- 学习RxJava+Retrofit+OkHttp+MVP的网络请求使用
公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了. 我在网上找了很多文章,写的都很详细,比如 https://www.jianshu.com/u/5fd2523645da https://www. ...
随机推荐
- 利用Jmeter模拟Github登录
最近学习了Jmeter的简单操作,很想找点东西来实战一下,因为我之前写过一篇通过Python模拟登录的文章,于是便想尝试下学习通过Jmeter来模拟登录. 本人环境:Jmeter5.1.1 关于Git ...
- Java连载5-标识符、关键字和字面值
一.标识符 1.标识符定义:在java源程序中凡是可以自己命名的单词 2.标识符可以标识什么元素? (1)类名(2)方法名(3)变量名(4)接口名(5)常量名 等等 3.标识符的命名要求 (1)一个合 ...
- 实例解说AngularJS在自动化测试中的应用
一.什么是AngularJS ? 1.AngularJS是一组用来开发web页面的框架.模板以及数据绑定和丰富UI的组件: 2.AngularJS提供了一系列健壮的功能,以及将代码隔离成模块的方法: ...
- 数据结构丨N叉树
遍历 N叉树的遍历 树的遍历 一棵二叉树可以按照前序.中序.后序或者层序来进行遍历.在这些遍历方法中,前序遍历.后序遍历和层序遍历同样可以运用到N叉树中. 回顾 - 二叉树的遍历 前序遍历 - 首先访 ...
- CDQZ集训DAY2 日记
依然很爆炸. T1上来有50分暴力分,打完后注意到了后50分的随机数据,开始想怎么去对付他.然后就开始思考随机数据意味着什么.想了想,想打一个扫描线或者分治.决策了一下还是打了一个扫描线+链表.然而只 ...
- 20131209-数据库导入导出数据-sqlhelper-第十七天
[1] 导出数据 namespace _05导出数据 { class Program { static void Main(string[] args) { string str = "Da ...
- 【题解】P2916 [USACO08NOV]安慰奶牛Cheering up the Cow-C++
原题传送门 这道题用最小生成树来完成,我选用的是kruskal(克鲁斯卡尔)来完成.这道题目在克鲁斯卡尔模板的基础上,有变动的地方只有2处:1.因为必须从一个点出发,而最小生成树最后会让所有点都连通, ...
- Git常用操作指南
目录 前言 Git简介 安装之后第一步 创建版本库 本地仓库 远程仓库 版本控制 工作区和暂存区 版本回退 撤销修改 删除文件 分支管理 创建与合并分支 解决冲突 分支管理策略 状态存储 多人协作 R ...
- 小埋的Dancing Line之旅:比赛题解&热身题题解
答疑帖: 赞助团队:UMR IT Team和洛谷大佬栖息地 赛后题解:更新了那两道练手题的题解 赛时公告,不过一些通知也可能在团队宣言里发出 如果各位发现重题,请将你认为重复的题目链接连同这次比赛的题 ...
- JVM调优之探索CMS和G1的物理内存归还机制
前言: 公司有一个资产统计系统,使用频率很低,但是要求在使用时查询速度快,因此想到做一些缓存放在内存中,在长时间没有使用,持久化到磁盘中,并对垃圾进行回收,归还物理内存给操作系统,从而节省宝贵资源给其 ...