RxSwift 源码解析02:Observable 不同创建方式

本文主要是介绍 Observable 不同的创建方式

基本名词解析

Observable

  • 可监听序列
  • 是事件的生产者

举例:温度是一个序列,然后检测温度,并对这个值做出响应

  • 当温度达到 33 度事,打开空调降温

Observable 也分为 有限观察序列无限观察序列,这里以 timer 为例

  • 有限观察序列:观察之前就已经明确观察的次数,例如 just、of、from等
  • 无限观察序列:观察次数不明确

这里以 timer 为例

  • 有限的timer(不加period):只观察一次
let ob = Observable<Int>.timer(.seconds(1), scheduler: MainScheduler.instance)
ob.subscribe { num **in**
    print(num)
}onCompleted: {
    print("done")
}.disposed(by: disposeBag)

//打印
done
  • 无限的timer(加period):会一直观察下去
let ob = Observable<Int>.timer(.seconds(1), period: .seconds(2), scheduler: MainScheduler.instance)
ob.subscribe { num **in**
    print(num)
}onCompleted: {
    print("done")
}.disposed(by: disposeBag)

//打印
done
done
...
done

Observer

  • 观察者
  • 用来监听事件,并对事件最初响应

监听当前室内温度,当高于33度时,打开空调降温
打开空调降温就是观察者

RxSwift 创建方式

Observable 序列的创建有以下一些方式

创建方式 说明
empty 创建一个空的序列,但是只能订阅到 complete
just 创建一个只有一个元素的 Observable 队列,订阅完信息自动 complete
of 创建一个固定数量元素的 Observable 序列
from 从一个序列(如 Array/Dictionary/Set)中创建一个 Observable 序列
deferred 为每一个订阅者创建一个新的 Observable 序列
generate 创建一个 Observable 序列,只需提供的条件值为 true 就可以生成值
error 创建一个不会发送任何条目并且立即终止错误的 Observable 序列
range 创建一个 Observable 序列,它会发出一系列的整数,然后终止
timer 获取计时器 Observable 序列
interval 底层就是 timer
repeatElement 创建一个可以无限发出给定元素Event 的 Observable 序列,即永不终止
never 创建一个永远不会发出Event(也不会终止)的 Observable 序列

empty 创建

  • 创建一个空的序列

原本序列事件是Int类型的,但这里调用emty函数 ,即没有序列,只能走 complete

let emtyOb = Observable<Int>.empty()
_ = emtyOb.subscribe(onNext: { num in
    print(num)
}, onError: { error in
    print(error)
}, onCompleted: {
    print("完成")
}, onDisposed: {
    print("释放")
})

//-------打印--------
完成
释放

just 创建

  • 单个信号序列创建(例如:viewModel/VC建立依赖关系)
let array = ["Lily", "Tom"]
Observable<[String]>.just(array)
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)

//-------打印--------
next(["Lily", "Tom"])
completed

of 创建

  • 多个元素 ,即针对序列处理
Observable<String>.of("Lily", "Tom")
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)


//-------打印--------
next(Lily)
next(Tom)
completed
  • 数组
Observable<[String]>.of(["Lily", "Tom"])
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)

//-------打印--------
next(["Lily", "Tom"])
completed
  • 字典
Observable<[String: Any]>.of(["name1": "Tom", "name2": "Lily"])
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)

//-------打印--------
next(["name2": "Lily", "name1": "Tom"])
completed

from 创建

  • 从集合中获取序列:数组,集合,set 获取序列

有可选项处理 - 更安全

Observable<[String]>.from(optional: ["Lily", "Tom"])
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)


//-------打印--------
next(["Lily", "Tom"])
completed

deferred 创建

  • 使用deferred()方法延迟Observable序列的初始化,通过传入的block来实现Observable序列的初始化并且返回。
  • 使用场景:登录/注册属于同一个页面时,动态判断不同逻辑

需求:动态序列 - 根据外界的标识 - 动态输出

var isOdd = true
_ = Observable<Int>.deferred({ () -> Observable<Int> in
    // 设计的序列
    isOdd = !isOdd
    if isOdd {
        return Observable.of(1, 3, 5, 7, 9)
    }
    return Observable.of(0, 2, 4, 6, 8)
})
.subscribe({ event in
    print(event)
})


//-------打印--------
next(0)
next(2)
next(4)
next(6)
next(8)
completed

generate 创建

  • 该方法创建一个只有当提供的所有的判断条件都为 true 的时候,才会给出动作的 Observable 序列。
  • 初始值给定 --> 然后判断条件1 --> 再判断条件2 --> 会一直递归下去,直到条件1或者条件2不满足
  • 类似 数组遍历循环
Observable.generate(initialState: 0, //初始值
                        condition: { $0 < 10}, //条件1
                        iterate: { $0 + 2 }) //条件2
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)


//-------打印--------
next(0)
next(2)
next(4)
next(6)
next(8)
completed
  • 数组遍历
let arr = ["1", "2", "3", "4"]
Observable.generate(initialState: 0,// 初始值
                    condition: { $0 < arr.count}, // 条件1
                    iterate: { $0 + 1 })  // 条件2 +2
.subscribe(onNext: {
    print("遍历arr:", arr[$0])
}).disposed(by: disposeBag)


//-------打印--------
遍历arr: 1
遍历arr: 2
遍历arr: 3
遍历arr: 4

error 创建

  • 对消费者发出一个错误信号
Observable<String>.error(NSError.init(domain: "lgerror", code: 10086, userInfo: ["reason": "unknow"]))
    .subscribe { event in
        print("订阅:", event)
    }
    .disposed(by: disposeBag)

range 创建

  • range:生成指定范围内的可观察整数序列。
Observable.range(start: 2, count: 5)
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)


//-------打印--------
next(2)
next(3)
next(4)
next(5)
next(6)
completed

timer创建

  • 第一次参数:第一次响应距离现在的时间
  • 第二个参数:时间间隔
  • 三个参数:线程
  • 如果没有指定期限 period,故认定为一次性
  • 使用场景:需要自定义定时器
Observable<Int>.timer(.seconds(5), period: .seconds(2), scheduler: MainScheduler.instance)
    .subscribe { event in
        print(event)
    }
    .disposed(by: disposeBag)

// 因为没有指定期限period,故认定为一次性
Observable<Int>.timer(.seconds(1), scheduler: MainScheduler.instance)
    .subscribe { event in
        print("111111111 \(event)")
    }
    

interval 创建

  • 封装好的定时器
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .subscribe { event in
        print(event)
    }

repeatElement 创建

  • 该方法创建一个可以无限发出给定元素的 Event的 Observable 序列(永不终止)
Observable<Int>.repeatElement(5)
    .subscribe { event in
        // print("订阅:", event)
    }
    .disposed(by: disposeBag)

never 创建

  • 该方法创建一个永远不会发出 Event(也不会终止)的 Observable 序列。
  • 这种类型的响应源 在测试或者在组合操作符中禁用确切的源非常有用
Observable<String>.never()
    .subscribe { event in
        print("886", event)
    }
    .disposed(by: disposeBag)

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

推荐阅读更多精彩内容