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) {
    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

RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第1张图片
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) {
    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


RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第2张图片
Filter

FlatMap(Transforming)

和 Kotlin List 的 flatMap 相似

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

// 6.3.kt
import io.reactivex.Observable

fun main(args: Array) {
    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(和之前的有些不太一样, 这个是 形状风格 的, 之前是 数字风格 的)

RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第3张图片
FlatMap

DefaultIfEmpty(Conditional and Boolean)

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

// 6.4.kt
import io.reactivex.Observable

fun main(args: Array) {
    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) {
    Observable.range(0, 10)
            .filter { it > 15 }
            .defaultIfEmpty(15)
            .subscribe(observer)
}

输出

New Subscription
Next 15
All Completed

Marble Diagram

RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第4张图片
DefaultIfEmpty

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

StartWith(Combining)

// 6.6.kt
import io.reactivex.Observable

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

输出

New Subscription
Next 1
Next 2
Next 3
All Completed

Marble Diagram


RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第5张图片
StartWith

Count(Mathematical and Aggregate)

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

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

输出

6

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

RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第6张图片
Count

Scan(和 Map 一样, 是 Transforming)

// 6.8.kt
import io.reactivex.Observable

fun main(args: Array) {
    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

RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第7张图片
Scan

Scan 接受一个有两个参数的函数为参数, 函数的第一个参数为累计值, 第二个参数为当前值, 这个函数返回一个值, 返回值被放在新的 Observable 中(同前,这里的 新的 也不准确)
RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram_第8张图片

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

import io.reactivex.Observable

fun main(args: Array) {
    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

你可能感兴趣的:(RxKotlin 例子不超过15行教程 6----Operator 与 Marble Diagram)