前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【译】使用RxJava从多个数据源获取数据

【译】使用RxJava从多个数据源获取数据

作者头像
用户1740424
发布于 2018-07-23 08:11:59
发布于 2018-07-23 08:11:59
2.6K00
代码可运行
举报
文章被收录于专栏:程序员Gank程序员Gank
运行总次数:0
代码可运行

  • 原文链接: Loading data from multiple sources with RxJava
  • 原文作者: Daniel Lew
  • 译文出自: 小鄧子的简书
  • 译者: 小鄧子
  • 校对者: hi大头鬼hi
  • 状态: 完成
  • 译者注:为了方便因Lambda(译文)还不够了解的同学进行阅读,本篇译文替换了原作中全部Lambda表达式。

试想,需要一些动态数据的时候,只要每次都请求网络就可以了。但是,更有效率的做法是,把联网得到的数据,缓存到磁盘或内存。

具体的说,计划如下:

  1. 偶尔的联网操作,只为获取最新数据。
  2. 尽可能快的读取到数据(通过获取之前缓存的网络数据)。

我将通过使用 RxJava,来实现这个计划。

基本模式

为每一个数据源(网络,磁盘和内存)创建Observable<Data>,使用concat()first()操作符,构造一个简单的实现方式。

concat()操作符持有多个Observable对象,并将它们按顺序串联成队列。 first()操作符只从串联队列中取出并发送第一个事件。因此,如果使用concat().first(),无论多少个数据源,只有第一个事件会被检索出并发送。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Our sources (left as an exercise for the reader)
Observable<Data> memory = ...;  
Observable<Data> disk = ...;  
Observable<Data> network = ...;
// Retrieve the first source with data
Observable<Data> source = Observable  
  .concat(memory, disk, network)
  .first();

这种模式的关键在于concat()操作符只有需要数据的时候才会订阅所有的Observable数据源。由于first()操作符会较早的停止检索队列,所以,如果存在缓存数据,就没有必要访问较慢的数据源。 也就是说,如果memory返回结果,就不必担心disknetwork会被访问。相反地,如果内存磁盘都没有数据,才执行网络请求。

注意concat()所持有的Observable数据源,是按照一个接一个的顺序被检索的。

持久化数据

很明显,下一步是缓存数据。如果不把网络请求后的结果缓存到磁盘,磁盘访问后的结果缓存到内存,那么这根本不就不叫缓存。接下来要写的代码就是,网络数据的持久化操作。

我的解决方案是,让每个数据源在发送完事件后,都保存或者缓存数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 Observable<Data> networkWithSave = network.doOnNext(new Action1<Data>() {
 @Override public void call(Data data) {
 saveToDisk(data);
 cacheInMemory(data);
 }
});
 Observable<Data> diskWithCache = disk.doOnNext(new Action1<Data>() {
 @Override public void call(Data data) {
  cacheInMemory(data);
 }
});

现在,如果你使用networkWithSavediskWithCache,数据将会在加载后自动保存。

(这個策略的另一个优势在于networkWithSavediskWithCache可以在任何地方被使用,不局限于我们的多数据模式下。)

陈旧的数据

不幸的,现在我们保存数据的那些代码,执行的有点过头了。无论数据是否过时,它总是返回相同的数据。我们希望做到,偶尔连接服务器抓取最新的数据。

解决方法在于,使用first()操作符进行过滤。就是设置它拒绝接收毫无价值的数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Observable<Data> source = Observable
    .concat(memory, diskWithCache, networkWithSave)
    .first(new Func1<Data, Boolean>() {
      @Override public Boolean call(Data data) {
        return data.isUpToDate();
      }
    });

现在,我们只需要发送被断定为最新数据的事件就OK了。因此,只要有一个数据源的数据过期,就继续检索下一个数据源,直到找到最新数据为止。

first()takeFirst()操作符的比较

对于这种设计模式,first()takeFirst()操作符可以二选其一。

两种调用方式的区别在于,如果所有数据源的数据均过期,没有任何的有效数据作为事件发送,first()会抛出NoSuchElementException异常(译者注:first()操作符均 return false),而takeFirst()操作符则直接调用完成操作,不会抛出任何异常。

使用哪个操作符,完全取决于是否需要明确处理缺失的数据。

代码示例

可以从这里检出,以上所有代码的实现示例:https://github.com/dlew/rxjava-multiple-sources-sample。

如果需要一个真实示例,检出 Gfycat App,它在获取数据的时候使用了这种模式。项目并没有使用以上展示的所有功能(因为不需要),但是,示范了concat().first()的基本用法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员Gank 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例
之前写过一系列RxJava1的文章,也承诺过会尽快有RxJava2的介绍。无奈实际项目中还未真正的使用RxJava2,不敢妄动笔墨。所以这次还是给大家分享一个使用RxJava1解决问题的案例,希望对大家在使用RxJava的时候有一点点启发。对RxJava还不了解的同学可以先去看看我之前的RxJava系列文章: RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从
张磊BARON
2018/04/13
1.4K0
RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例
RxJava(三) flatMap 操作符用法详解
还是以上一篇map操作符的例子吧,如果对 map操作符 不是很了解的,可以看看我之前的文章。
全栈程序员站长
2022/09/05
1.8K0
RxJava从入门到不离不弃(一)——基本概念和使用
RxJava的编程思想已经在Android开发者中变得越来越流行。有个不好的点就是上手不太容易,尤其是大部分人之前都是使用命令式编程语言。
蜻蜓队长
2018/08/03
7920
RxJava从入门到不离不弃(一)——基本概念和使用
【译】对RxJava中-repeatWhen()和-retryWhen()操作符的思考
第一次见到.repeatWhen()和.retryWhen()这两个操作符的时候就非常困惑了。不得不说,它们绝对是“最令人困惑弹珠图”的有力角逐者。
用户1740424
2018/07/23
2.1K0
【译】对RxJava中-repeatWhen()和-retryWhen()操作符的思考
【译】使用RxJava代替EventBus类库
如今的Android社区,人人都在讨论RxJava以及为什么我们应该在项目中使用RxJava。当我们开始在Android项目中使用RxJava的时候,就已经意识到了,我们的代码库可以不再需要Otto了(或其他事件总线类库)。
用户1740424
2018/07/23
4430
【译】使用RxJava代替EventBus类库
【译】RxJava变换操作符:-concatMap(-)与-flatMap(-)的比较
是时候回归写作了。(译者注:原作者吧啦吧啦唠家常,这里就不做翻译了,但是,有两个重要的链接,点我,再点我)
用户1740424
2018/07/23
8240
【译】RxJava变换操作符:-concatMap(-)与-flatMap(-)的比较
RxAndroid从零开始学之五(常见操作符与三级缓存)
RxAndroid的操作符有很多,本以为写了上一节的一些基本的Operator就可以正常编写代码了,但是后来在github上看googlesample,发现了一些另外的Operator。那么本文就继续介绍这些operator并加上自己的一些理解。
Frank909
2019/01/14
6350
【译】使用RxJava实现延迟订阅
我越来越喜欢把RxJava的defer()操作符作为一个工具来使用,以确保Observable代码在被订阅后才执行(而不是创建后立即执行)。我之前写过一些有关defer()的代码,但是,现在我想做更详细的描述。
用户1740424
2018/07/23
8390
【译】使用RxJava实现延迟订阅
【译】避免打断链式结构:使用.compose( )操作符
*[Chains break by the weakest link](https://www.flickr.com/photos/hernanpc/7115374283)*
小鄧子
2018/08/20
6610
RxJava简析
rxjava文档地址https://mcxiaoke.gitbooks.io/rxdocs/content/ 这个是中文版的
用户3112896
2020/11/25
7350
Android RxJava 实战系列:从磁盘 / 内存缓存中 获取缓存数据
Carson_Ho的Github地址 = RxJava2实战系列:从磁盘 / 内存缓存中 获取缓存数据
Carson.Ho
2019/02/22
2K0
Android应用架构
来源: 小鄧子(@Rx小鄧子) Android开发生态圈的节奏非常之快。每周都会有新的工具诞生,类库的更新,博客的发表以及技术探讨。如果你外出度假一个月,当你回来的时候可能已经发布了新版本的Support Library或者Play Services 我与Ribot Team一起做Android应用已经超过三年了。这段时间,我们所构建的Android应用架构和技术也在不断地演变。本文将向您阐述我们的经验,错误以及架构变化背后的原因。 曾经的架构 追溯到2012年我们的代码库使用的是基本结构,那个时候我们没有
编程范 源代码公司
2018/04/16
1.3K0
Android应用架构
【译】RxJava中的事件广播
如果你想多点传播一个事件,也就是向所有的下游操作符或订阅者发送同一个事件。这在做耗时操作如网络请求等场景来讲是非常有用的。你不需要为每个订阅者做重复的网络请求,只需执行一次,然后传播响应结果即可。
用户1740424
2018/07/23
8270
【译】RxJava中的事件广播
RxJava三问—基础知识点回顾
然后开始提问题了,Rxjava涉及的内容很多,我还是会以三个问题为单位,从易到难,一篇篇的说下去,今天的三问是:
码上积木
2020/12/11
6280
Android RxJava应用:合并数据源
Rxjava由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎。
Carson.Ho
2022/03/25
7940
Android RxJava应用:合并数据源
大佬们,一波RxJava 3.0来袭,请做好准备~
每个Android开发者,都是爱RxJava的,简洁线程切换和多网络请求合并,再配合Retrofit,简直是APP开发的福音。不知不觉,RxJava一路走来,已经更新到第三大版本了。不像RxJava 2对RxJava 1那么残忍,RxJava 3对RxJava 2的兼容性还是挺好的,目前并没有做出很大的更改。RxJava2到2020年12月31号不再提供支持,错误时同时在2.x和3.x修复,但新功能只会在3.x上添加。
Rouse
2019/07/17
1.9K0
大佬们,一波RxJava 3.0来袭,请做好准备~
一篇博客让你了解RxJava
RxJava可以说是2016年最流行的项目之一了,最近也接触了一下RxJava,于是想写一篇博客,希望能通过这篇博客让大家能对其进行了解,本篇博客是基于RxJava2.0,跟RxJava1.0还是有很多不同的
老马的编程之旅
2022/06/22
5440
一篇博客让你了解RxJava
【译】RxJava中的事件广播
如果你想多点传播一个事件,也就是向所有的下游操作符或订阅者发送同一个事件。这在做耗时操作如网络请求等场景来讲是非常有用的。你不需要为每个订阅者做重复的网络请求,只需执行一次,然后传播响应结果即可。
小鄧子
2018/08/20
5980
【译】RxJava中的事件广播
Android RxJava 实战讲解:合并数据源 & 同时展示数据
前言 Rxjava,由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎。 如果还不了解RxJava,请看文章:Android:这是一篇 清晰 & 易懂的R
Carson.Ho
2019/02/22
3.6K2
RxJava 2.0还没熟悉,RxJava 3.0说来就来了!(多种操作符代码详解篇)
在上篇文章中讲的是关于Rxjava的基础篇,今天来讲讲多种操作符的具体内容,操作符太多了,大家准备好啊,耐心看~
Android技术干货分享
2019/07/19
2.2K0
RxJava 2.0还没熟悉,RxJava 3.0说来就来了!(多种操作符代码详解篇)
推荐阅读
相关推荐
RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验