Rx概述(RxJava2)

前言:

这是一个关于Rx的博文系列 ,也是本人第一次通过网络来记录、整理自己的学习历程。若有纰漏之处,尤其是错误的理解和观点,请各位大神拍砖。

干货在后头呢。


Rx——Reactive Extension,使用可观测的序列(流)来组成异步的、基于事件的程序的库。我们使用Observable(数据流)描述数据序列,通过Operator(操作符)查询、改变数据流,并且支持以参数的形式利用Scheduler(调度器)控制异步数据流的并发。简而言之:Rx = Observable + Operator + Scheduler

若无特别说明,本系列文章中所出现的数据流和事件流均代表Observable。

我更愿意称之为一种编程方式——响应式编程。实际上Rx不止一个库,它包括了多个实现了Rx方式的各种编程语言的开源库。如非特别说明,本系列文章均参考Rx的Java实现——RxJava2——进行阐述。


Rx扩展了观察者模式,使得该模式从对一个数据或事件的观察升级为对一个序列的数据或事件的观察,更强大的是它可通过操作符将多个数据序列组合成一个序列。借助于Rx我们能够更加专注于程序的逻辑,而不用过多地关注诸如多线程、同步、线程安全、并发、非阻塞IO这些底层的东东。

看到这里有人会质疑了:没有Rx我照样能得到想要的数据序列啊,谈何“升级”?这里以吃饭来举例。

场景一和场景二:

来到公司楼下的食堂——没错,就是那种去晚了菜都凉了的地方:

一)中午胃口不错,于是点了个两荤一素:Iterable<Dish> lunch = getDish(); eat(lauch);

二)晚上想减肥,只要了一个素菜:Dish dinner = getDish(); eat(dinner);

食堂的菜已经提前准备好了,想吃多少任君挑选。点好菜就开吃不用等待,可见在食堂吃饭是一个同步的操作。

场景三:

某个下午堆代码上瘾错过食堂饭点,只好去楼下的拉面馆吃面:

三) 老板,来碗牛肉炒刀削:Future<Dish> dinner = waitDish(); eat(lauch);

给牛肉炒刀削点赞!接下来就是等面出锅,可见吃面一个异步的操作。

场景四和场景五:

周末好不容易约了女神一起吃中餐:

为了这顿饭我饿了3天,服务员菜单递过来我底气十足地点了5个硬菜,女神却说要减肥(不早说)。为了体现我的绅士风度,饿死也必须等女神先吃。

四) 然而女神说等菜全部上齐了再吃:Future<Iterable<Dish>> lunch = waitDishAll(); eat(lauch);

五) 如果第一道菜上桌就开始吃我就不用饿那么久了:Iterable<Future<Dish>> lunch = waitDishAny(); eat(lauch);

可见吃大餐是一个由多个异步过程组合的操作,组合的方式由具体业务决定。

毫无疑问,我们能从容面对场景一和场景二;对于场景三,不同语言提供了类似功能的工具,比如Java提供了Future(配合Callback)来应对这类单一异步操作。然而在场景四和场景五中,存在多个、甚至可能嵌套的异步操作,考虑到异步操作在时间上地不确定性,尽管Future仍然可以作为一种解决方案,但随之而来的复杂性也不容忽视,程序员需要提供一些额外的逻辑来判断异步操作何时结束以及后续的操作(对应本场景中的吃)何时开始。

吃瓜群众开始起哄:Rx行那Rx上啊。

Observable<Dish> lauch = getDish(); // 得到数据流

5道菜上齐再吃: lauch.buffer(5).subscribe(eat); // 转换数据流 、订阅

第一道菜上桌就吃: lauch.firstElement().subscribe(eat); // 过滤数据流 、订阅

如何获取和响应包含多个数据的异步数据流,Java的Future+Callback方案显得有点笨拙,程序员不得不分散精力去处理核心业务之外的逻辑,编写出的代码也容易产生臭名昭著的“回调地狱”。相比之下,Rx表现得游刃有余,它提供了丰富的操作符(此处暂且按下不表),原始数据流(上游数据流)经若干次操作符处理后变成目标数据流(下游数据流)。观察者订阅了目标数据流后,剩下的工作就是集中精力处理后续业务。


Rx不但可以方便地处理单个数据——更重要的是——它在需要处理多个、甚至无限多个数据的场景中表现优异。因此,Rx的准则是:(几乎)一切都可以成为一个数据流(哪怕只有单个数据、甚至没有任何数据)。

Rx相比经典的观察者模式增加了两个能力:

1) 被观察者向观察者发送“没有更多数据”通知的能力(调用观察者的onComplete方法),类比于Iterable因 !hasNext()正常结束遍历。

2) 被观察者向观察者发送“异常”通知的能力 (调用观察者的onError方法),类比于Iterable遍历过程中抛出异常 提前结束遍历。

观察者只能收到以上两个通知其中之一。一旦收到任何一个通知,之后观察者将不会收到任何数据或通知。

获得以上两个能力的加持后,Rx的Observable与Iterable看起来就像是孪生兄弟,我们可以像使用Iterable一样使用Observable。

通过Iterable处理数据序列,用的是pull(拉取)的方式,处理过程发生在当前线程:

getDataFromLocalMemory()

    .skip(10)

    .take(5)

      .map({ s -> s + " transformed" })

    .forEach({ println "next -> " + it })

通过Observable处理数据序列,用的是push(推送)的方式,可以灵活地选择同步或异步地发送处理结果:

getDataFromNetwork()

    .skip(10)

    .take(5)

    .map({ s ->s + " transformed" })

    .subscribe({ println "onNext -> " + it })

Observable比它的孪生兄弟Iterable多了一对隐形的翅膀——在处理异步的数据流时,我们便可以打开这对翅膀。


Rx使用非常灵活,尽管我们通常用它来处理异步数据流,事实上,Rx完全不关心产生数据的方式,无论是通过线程池、event loops、non-blocking I/O、 actors。即便你已经通过线程池来产生数据,仍然可以改造成其他方式,而完全不用改变现有观察者的工作方式。

数据是同步or异步获取的?

数据序列是否需要在多个不同线程中计算并依次返回给调用者?

是否通过异步的网络请求来获取数据?

是否通过callback线程获取数据?

Rx把一切与Observable的交互视为异步的。

下一篇 >> Observable概述(RxJava2)

本系列将持续更新

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容