RxJava(八)concat符操作处理多数据源
欢迎转载,转载请标明出处:
http://blog.csdn.net/johnny901114/article/details/51568562
本文出自:【余志强的博客】
一、concat操作符概述
从concatMap操作我们知道,concat操作符肯定也是有序的,而concat操作符是接收若干个Observables,发射数据是有序的,不会交叉。
下面看看官方文档和流程图的说明:
Returns an Observable that emits the items emitted by three Observables,
one after the other, without interleaving them.

二、使用示例
示例一
下面使用concat操作符 来实现个多数据源的例子,比如一个商品详情需要展示商品的信息、艺术家信息、与该商品类似的商品,可能需要访问三个接口。这个时候就可以使用concat操作符。
卖家信息
private Observable<Object> sellerInfo = Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
Seller d = goodsApi.getSeller();
if (d != null) {
subscriber.onNext(d);
}
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
商品信息
private Observable<Object> goodsInfo = Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
Goods d = goodsApi.getGoodInfo();
if (d != null) {
subscriber.onNext(d);
}
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
类似作品推荐
private Observable<Object> relateGoods = Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
List<Goods> d = goodsApi.getRelateGoods();
if (d != null) {
subscriber.onNext(d);
}
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
Observable.concat(sellerInfo, goodsInfo, relateGoods)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object s) {
printLog(tvLogs, "Getting data from ", s);
//push data to ui
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
printLog(tvLogs, "Error: ", throwable.getMessage());
}
});
为什么泛型去设置成Object呢,因为Observable.concat只接受相同泛型的参数。
也许会有人问后去商品信息的时候没办法传递参数啊(比如商品ID), 在外面包一层方法即可,方法参数为goodID。
示例二
使用 concat操作符 对缓存进行检查,如:内存缓存、本地缓存、网络,那一层有数据立即返回。
使用一个数组来表示三个数据源:
String data[] = {null, null, "network"};
//String data[] = {null, "disk","network"};
//String data[] = {"memory", null,"network"};
//String data[] = {"memory", "disk",null};
//String data[] = {"memory", "disk","network"};
内存缓存
private Observable<String> memorySource = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
String d = data[0];
printLog(tvLogs, "", "----start check memory data. value is null? " + (d == null));
if (d != null) {
subscriber.onNext(d);
}
subscriber.onCompleted();
}
});
本地缓存
private Observable<String> diskSource = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
String d = data[1];
printLog(tvLogs, "", "----start check disk data. value is null? " + (d == null));
if (d != null) {
subscriber.onNext(d);
}
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
网络
private Observable<String> networkSource = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
String d = data[2];
printLog(tvLogs, "", "----start check network data. value is null? " + (d == null));
if (d != null) {
subscriber.onNext(d);
}
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io());
从例子1我们知道,concat会三个数据源都会请求的。如何使得哪层有数据就用哪层的,之后就不走后面的逻辑了。
可以配合first()操作符来实现这样的效果。
Observable.concat(memorySource, diskSource, networkSource)
.first()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
printLog(tvLogs, "Getting data from ", s);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
printLog(tvLogs, "Error: ", throwable.getMessage());
}
});
需要注意的是如果memorySource, diskSource, networkSource返回的都null,那么会报一个异常:
java.util.NoSuchElementException: Sequence contains no elements……
可以使用takeFirst操作,即使都没有数据,也不会报异常。
Observable.concat(memorySource, diskSource, networkSource)
//first()-> if no data from observables will cause exception :
//java.util.NoSuchElementException: Sequence contains no elements
//takeFirst -> no exception
.takeFirst(new Func1<String, Boolean>() {
@Override
public Boolean call(String s) {
return s != null;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
printLog(tvLogs, "Getting data from ", s);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
printLog(tvLogs, "Error: ", throwable.getMessage());
}
});
除了通过concat操作符来实现缓存逻辑,也可使用switchIfEmpty ,详细可以查看我的博客:
http://blog.csdn.net/johnny901114/article/details/52585912
RxJava(八)concat符操作处理多数据源的更多相关文章
- .NET LINQ 限定符操作
限定符操作 限定符运算返回一个 Boolean 值,该值指示序列中是否有一些元素满足条件或是否所有元素都满足条件. 方法 方法名 说明 C# 查询表达式语法 Visual Basic 查询表 ...
- TP5常用命令符操作
ThinkPHP5常用命令符操作 1. 模块自动生成指令: 默认会读取应用目录application下面的build.php作为自动 生成的定义文件,如果你的定义文件位置不同,则需要使用 ...
- C#路径的八种相关操作,判断字符串是否为路径等
原文:C#路径的八种相关操作,判断字符串是否为路径等 1.判定一个给定的C#路径是否有效,合法 通过Path.GetInvalidPathChars或Path.GetInvalidFileNameCh ...
- selenium webdriver学习(八)------------如何操作select下拉框(转)
selenium webdriver学习(八)------------如何操作select下拉框 博客分类: Selenium-webdriver 下面我们来看一下selenium webdriv ...
- RxJava的concat操作符
更多文章请点击:http://77blogs.com/?p=170 转载请标明出处:https://www.cnblogs.com/tangZH/p/12088332.html,http://77bl ...
- RxJava操作符(05-结合操作)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656736 本文出自:[openXu的博客] 目录: CombineLatest Join ...
- Django(十八)Model操作补充
参考博客:http://www.cnblogs.com/wupeiqi/articles/6216618.html 1. 创建类 class UserInfo(model.Model): age = ...
- 八.python文件操作
一,初识文件操作. 引子: 现在这个世界上,如果可以操作文件的所有软件都消失了,比如word,wps等等,此时你的朋友通过qq给你发过来一个文件,文件名是:美女模特空姐护士联系方式.txt,在座的所有 ...
- jQuery-1.9.1源码分析系列(八) 属性操作
jQuery的属性操作主要包括 jQuery.fn.val jQuery.fn.attr jQuery.fn.removeAttr jQuery.fn.prop jQuery.fn.removePro ...
随机推荐
- [LeetCode] Lonely Pixel II 孤独的像素之二
Given a picture consisting of black and white pixels, and a positive integer N, find the number of b ...
- enumerate给列表加序号
#coding=utf-8#给列表加上序号,enumerate(l1),默认从0开始l1=['money','house','joo']for item in enumerate(l1,1): #pr ...
- osx mitmproxy ssl 错误
记录一下,总是在这里折腾. cd ~ cd .mitmproxy cp mitmproxy-ca-cert.pem ~/ 然后到目录下双击mitmproxy-ca-cert.pem ,在钥匙串中的登录 ...
- AtCoder Grand Contest 021 D - Reversed LCS
Description Takahashi has decided to give a string to his mother. The value of a string T is the len ...
- hdu 5641 BestCoder Round #75
King's Phone Accepts: 310 Submissions: 2980 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- Gradle学习之部署上传项目
原先在公司做项目时,写了一个简单的基于gradle部署项目的脚本,今天翻出来记录一下 一.build.gradle buildscript { ext { env = System.getProper ...
- django rest-framework 2.请求和响应
一.请求对象 REST 框架引入Request来扩展常规的HttpRequest,并提供了更灵活的请求解析.Request对象的核心功能是request.data属性. 导入方式: from rest ...
- (转)Ensemble2015安装
1 IIS安装和windows系统配置 1.1 IIS安装 检查是否安装好了IIS,可在[管理工具]的[服务管理器]中查看,如下图所示表示安装了IIS. 确认IIS已完全安装,点击上图中的Web服 ...
- Python中list的功能介绍
List的功能介绍 1. 列表的两种方法 1. 列表的内置方法 列表的相加 格式:x.__add__(y)等同于x+y 例如:list1 = [1,2,3] print(list1.__add__([ ...
- C语言程序设计第三次作业——选择结构(1)
一.改错题 1.题目计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 源程序(有错误的程序): #include <stdio.h> int main ...