RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram

本节会以各种各样的 Operator 为例来看奇奇怪怪的 Marble Diagram

  • 本教程中所有 Operator 均依照 ReactiveX 规范, 首字母大写
  • 本节代码中的 observer 就是第二节中的
  • 本节中的 Map 是一种函数, 不是数据结构
  • 本节中所有 Marble Diagram 上面是 源 Observable 下面是生成的 Observable
  • 这一节重点是 Marble Diagram , 所以 Operator 不会选择很生僻的

本节术语的中文翻译

Operator 运算符
Marble Diagram 弹珠图

Operator 是什么

请允许我用前面举了很多次的例子做开头,不过这一次我会给它配图

// 6.1.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    val observable = Observable.just(1, 2, 3)
    observable.map { x -> 10 * x }.subscribe(observer)  // 这里完全可以用 10*it ,为了和下面的图片一致我没有这么做
}

输出

New Subscription
Next 10
Next 20
Next 30
All Completed

Marble Diagram

Map

Map 函数会把当前 Observable 中的每个值用传入的函数做一下变换再放入新的数据流中

  • 重点在 源 Observable 并不会被修改
  • 新的 这个词不恰当,因为这个计算有可能是 惰性的, 多次应用 Map 方法会在一次变换中完成,并不会创建多个 中间 Observable

上面例子中的 Map 就是一个 Operator (一会我们会更全面的理解它)。

链式 Operator (在 Kotlin 中的实现是 链式方法)

大多数 Operator 的作用对象可以Observable, 返回值可以Observable (还能作用到其他类型上,返回其他类型的值。之后会见到 Flowable Single 等类型)。所以我们可以一个接一个的使用 Operator ,每个 Operator 从上一个 Observable 中获取值经过变换传给下一个 Operator

Operator 的范畴(截止 2018.2.26)

目前 ReactiveX 规范共定义有 454 个 Operator (Observable Operator 列表)
这里先概述一下,之后分别介绍。按照 ReactiveX 规范, Operator 有如下几类。

名称 职能 代表
Creating 创建新的 Observable Just
Transforming 源 Observable 中的值进行变换后弹出 Map
Filtering 源 Observable 中的值选择性地弹出 Filter
Combining 把多个 源 Observable 处理为一个 Observable Zip
Error Handling 失败恢复 Retry
Observable Utility 工具集 Subscribe
Conditional and Boolean 条件相关 DefaultIfEmpty
Mathematical and Aggregate 数学,聚合相关 Max
Backpressure 用于处理 Observable 弹射值的速度远大于 Observer 接收的速度的情况(下一节介绍)
Connectable Observable 源 Observable 转换成一个 特化Observable, 使其满足特定要求(如 精确订阅) Publish
Convert Observable 变成另一种对象或数据结构 To

ReactiveX 在很多平台上都有相应实现(如 RxJava RxJS Rx.NET 等等)
这些实现是有一些差异的 (如 Rx.NETSelectMany Operator 对应 ReactiveXFlatMap Operator, 而这个 OperatorRxKotlin 中叫 flatMap)

这套教程的最后会有一个 决策树 帮助你选择合适的 Operator 解决遇到的问题。
那么下面来看各种 OperatorMarble Diagram

Marble Diagram

接下来我们用各大范畴的 OperatorMarble Diagram

Filter(Filtering)

// 6.2.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    val observable = Observable.just(2, 30, 22, 5, 60, 1)
    observable.filter { x -> x > 10 }.subscribe(observer)  // it > 10
}

输出

New Subscription
Next 30
Next 22
Next 60
All Completed

Marble Diagram


Filter

FlatMap(Transforming)

和 Kotlin List 的 flatMap 相似

多说一句, MapFunctor 的方法,FlatMapMonad 的方法。
这篇教程不是专门讲函数式的, 此处不展开。有兴趣的话可以看 第二节 的参考链接

// 6.3.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    val observable = Observable.just(1, 5, 9)  // 数字没有特殊含义
    observable
            .flatMap { x -> Observable.just(x + 1, x + 2) }  // 这个例子非常牵强
            .subscribe(observer)
}

输出

New Subscription
Next 2
Next 3
Next 6
Next 7
Next 10
Next 11
All Completed

Marble Diagram(和之前的有些不太一样, 这个是 形状风格 的, 之前是 数字风格 的)

FlatMap

DefaultIfEmpty(Conditional and Boolean)

Observable 中没有值的时候,我们订阅什么也得不到。比如下面的例子

// 6.4.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    Observable.range(0, 10)
            .filter { it > 15 }
            .subscribe(observer)
}

输出

New Subscription
All Completed

看, 什么也没有
那如果我们想在 Observable 没有值的时候给出一个默认值呢, 见下例

// 6.5.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    Observable.range(0, 10)
            .filter { it > 15 }
            .defaultIfEmpty(15)
            .subscribe(observer)
}

输出

New Subscription
Next 15
All Completed

Marble Diagram

DefaultIfEmpty

注意看图, 因为之前没有值,所以 源 Observable 的终点变为一个值, 又生成了一个新的终点。

StartWith(Combining)

// 6.6.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    Observable.just(2, 3)
            .startWith(1)
            .subscribe(observer)
}

输出

New Subscription
Next 1
Next 2
Next 3
All Completed

Marble Diagram


StartWith

Count(Mathematical and Aggregate)

import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.rxkotlin.subscribeBy

fun main(args: Array<String>) {
    // Single 会在之后介绍
    val count:Single<Long> = Observable.just(2, 30, 22, 5, 60, 1).count()
    // subscribeBy 会在之后介绍
    count.subscribeBy { println(it) }
}

输出

6

Marble Diagram(这个图和上面的代码不一致, 因为 RxKotlin 貌似没有办法在 count 后面加参数)

Count

Scan(和 Map 一样, 是 Transforming)

// 6.8.kt
import io.reactivex.Observable

fun main(args: Array<String>) {
    Observable.just(1, 2, 3, 4, 5)
            .scan { x, y -> x + y }
            .subscribe(observer)
}

输出

New Subscription
Next 1
Next 3
Next 6
Next 10
Next 15
All Completed

Marble Diagram

Scan

Scan 接受一个有两个参数的函数为参数, 函数的第一个参数为累计值, 第二个参数为当前值, 这个函数返回一个值, 返回值被放在新的 Observable 中(同前,这里的 新的 也不准确)

再来看一个 Scan 的例子 (这个例子是为了更进一步了解 Scan, 不是为了演示 Marble Diagram)

import io.reactivex.Observable

fun main(args: Array<String>) {
    Observable.just("1", "2", "3", "4", "5")
            .scan { x, y -> x + " " + y }
            .subscribe(observer)
}

输出

New Subscription
Next 1
Next 1 2
Next 1 2 3
Next 1 2 3 4
Next 1 2 3 4 5
All Completed

这一节 OK 了,明天我们说 Backpressure

RxKotlin 例子不超过15行教程 1----环境配置与初体验

RxKotlin 例子不超过15行教程 2----Observable Observer 与 Subscribe 简介

RxKotlin 例子不超过15行教程 3----Observable 的创建

RxKotlin 例子不超过15行教程 4----Observer Subscribe 与 Hot/Cold Observable

RxKotlin 例子不超过15行教程 5----Subject

RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram

RxKotlin 例子不超过15行教程 7----Backpressure Flowable 与 Subscriber 简介

RxKotlin 例子不超过15行教程 8----Error Handling

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

推荐阅读更多精彩内容

  • 上一节中我们说到了 Hot Observable 的一个实现 ---- ConnectableObservable...
    蔡洪宇阅读 1,520评论 0 1
  • http://blog.csdn.net/yyh352091626/article/details/5330472...
    奈何心善阅读 3,507评论 0 0
  • 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy阅读 5,382评论 7 62
  • 介绍 RxJS是一个异步编程的库,同时它通过observable序列来实现基于事件的编程。它提供了一个核心的类型:...
    泓荥阅读 16,505评论 0 12
  • 【感悟】 1.将文章或分享发给你敬佩或欣赏的老师、同学、朋友,征求反馈意见后再优化、调整,不仅可提高文章或分享的质...
    1军哥嘹亮阅读 357评论 0 0