RxSwift 教程 学习
来源:互联网 发布:淘宝一元规则 编辑:程序博客网 时间:2024/05/16 10:38
RxSwift 教程 学习 基础总结
最近对RxSwift比较感兴趣, 看了一下官方的工程 , 跟其中的playground学习了基本的语法, 进入正题:
还要说一点, 一下内容大部分甚至绝大部分都是来自官方工程
有兴趣的clone下来看看
博客目前正在整理中可能有点慢, 我会尽快完成, 有兴趣可以先看我学习用的demo (如果感觉不错请给个star)
附上官网链接
目录
- RxSwift 教程 学习 基础总结
- 目录
- 导入RxSwift
- 基本语法
- empty
- never
- just
- sequenceOf
- toObservable
- create
- error
- generate
- deferred
- Subjects
- PublishSubject
- ReplaySubject
- BehaviorSubject
- Variable
- function
- map
- FlatMap
- Scan
- Filter
- DistinctUntilChanged
- Take
- Combining
- StartWith
- Zip
- Merge
- SwitchLatest
- CatchError
- Retry
- Subscribe
- DoOn
- Take
- Concat
- reduce
- 总结
导入RxSwift
如果你还没有吧RxSwift导入到你的工程中的话, 先导入工程(ps: 已经导入的请跳过)
基本语法
在这之前需要创建两个方法, 以供一会使用;
public func example(description: String, action: () -> ()) { print("\n--- \(description) example ---") action()}public func delay(delay:Double, closure:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)) ), dispatch_get_main_queue(), closure)}
empty
empty看名字就知道, 他只会发送一个.Completed信号
example("empty", action: { let emptySequence: Observable<Int> = Observable<Int>.empty() let _ = emptySequence .subscribe { event in print(event) } })
打印结果为:
— empty example —
Completed
never
never 是一个不会发送任何信号的序列
example("never") { let neverSequence: Observable<Int> = Observable<Int>.never() let _ = neverSequence .subscribe { _ in print("This block is never called.") } }
打印结果为:
— never example —
just
just 只会发送两个信号, 首先是参数value, 然后是.Completed
example("just") { let singleElementSequence:Observable<[String]> = Observable.just(["aaa", "bbb"]) let _ = singleElementSequence .subscribe { event in print(event) } }
打印结果为:
— just example —
Next([“aaa”, “bbb”])
Completed
sequenceOf
sequenceOf 是会吧传入的几个value 转化成信号 依次发出
example("sequenceOf") { let sequenceOfElements = Observable.of(["aaa", "bbb"], ["ccc", "ddd"], ["eee", "fff"], ["ggg", "hhh"]) let _ = sequenceOfElements .subscribe { event in print(event) } }
打印结果为:
— sequenceOf example —
Next([“aaa”, “bbb”])
Next([“ccc”, “ddd”])
Next([“eee”, “fff”])
Next([“ggg”, “hhh”])
Completed
toObservable
toObservable 可以把任意符合SequenceType的转换成Observable
example("toObservable") { let sequenceFromArray = [1, 2, 3, 4, 5].toObservable() let _ = sequenceFromArray .subscribe { event in print(event) } }
打印结果:
— toObservable example —
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Completed
create
create 手动创建一个信号, 信号内容可自行定义
example("create") { let myJust = { (singleElement: Int) -> Observable<Int> in return Observable.create { observer in let error = NSError(domain: "aaaaaa", code: 10000, userInfo: nil) observer.on(.Next(singleElement)) if singleElement % 2 == 0 { observer.onError(error) } else { observer.on(.Completed) } return NopDisposable.instance } } let _ = myJust(6) .subscribe { event in print(event) } }
打印结果:
— create example —
Next(6)
Error(Error Domain=aaaaaa Code=10000 “(null)”)
Next(5)
Completed
error
error就是发送一个标志着错误的信号
example("failWith") { let error = NSError(domain: "Test", code: -1, userInfo: nil) let erroredSequence: Observable<Int> = Observable.error(error) let _ = erroredSequence .subscribe { event in print(event) } }
打印结果:
— failWith example —
Error(Error Domain=Test Code=-1 “(null)”)
generate
generate生成一个条件环境, 把再这个环境中的符合条件的信号发送出去
example("generate") { let generated = Observable.generate( initialState: 0, // 初始状态 condition: { $0 < 3 }, // 条件 iterate: { $0 + 1 } // 重复 ) let _ = generated .subscribe { event in print(event) } }
打印结果:
— generate example —
Next(0)
Next(1)
Next(2)
Completed
deferred
deferred是只有在有订阅的时候才会创建一个Observable, 这样的好处就在于创建Observable的时候 保证了数据是最新的, 例如:
example("deferred") { var value = 1; let normalCreate: Observable<Int> = Observable.just(value) let deferredSequence: Observable<Int> = Observable.deferred { return Observable.create { observer in observer.on(.Next(value)) observer.on(.Completed) return NopDisposable.instance } } value = 10 _ = normalCreate .subscribe{ print("normal-\($0)") } _ = deferredSequence .subscribe { print("defer-\($0)") } }
打印结果:
— deferred example —
normal-Next(1)
normal-Completed
defer-Next(30)
defer-Completed
Subjects
Subjects 是一个既可以订阅又可以被订阅. 类似一个管道, 控制着内容的变化和输出
接下来的内容需要先定义一个辅助函数用于输出数据:
let disposeBag = DisposeBag() func writeSequenceToConsole<O: ObservableType>(name: String, squence: O) { squence.subscribe { e in print("Subscription: \(name), event: \(e)") }.addDisposableTo(disposeBag) }
PublishSubject
PublishSubject 的订阅者只会接收到从它订阅以后发送的信号
example("PublishSubject") { let subject = PublishSubject<String>() self.writeSequenceToConsole("1", squence: subject) subject.onNext("a") subject.onNext("b") self.writeSequenceToConsole("2", squence: subject) subject.onNext("c") subject.onNext("d") }
打印结果:
— PublishSubject example —
Subscription: 1, event: Next(a) —- 订阅者1开始订阅
Subscription: 1, event: Next(b)
Subscription: 1, event: Next(c)
Subscription: 2, event: Next(c) —- 订阅者2开始订阅
Subscription: 1, event: Next(d)
Subscription: 2, event: Next(d)
ReplaySubject
ReplaySubject 在新的订阅出现的时候会补发前几条数据, bufferSize控制着具体补发前边几条数据 , 1就是补发一条, 2就是补发两条, 以此类推
example("ReplaySubject") { let subject = ReplaySubject<String>.create(bufferSize: 2) self.writeSequenceToConsole("1", squence: subject) subject.onNext("a") subject.onNext("b") self.writeSequenceToConsole("2", squence: subject) subject.onNext("c") subject.onNext("d") }
打印结果:
— ReplaySubject example —
Subscription: 1, event: Next(a) —- 订阅者1 开始订阅
Subscription: 1, event: Next(b)
Subscription: 2, event: Next(a) —- 订阅者2开始订阅, 并连续收到了订阅前的两组数据
Subscription: 2, event: Next(b)
Subscription: 1, event: Next(c)
Subscription: 2, event: Next(c)
Subscription: 1, event: Next(d)
Subscription: 2, event: Next(d)
BehaviorSubject
BehaviorSubject 在有新的订阅的时候 会发送最近发送的一条数据, 如果最近没有发送则发送默认值
example("BehaviorSubject") { let subject = BehaviorSubject<String>(value: "z") self.writeSequenceToConsole("1", squence: subject) subject.onNext("a") subject.onNext("b") self.writeSequenceToConsole("2", squence: subject) subject.onNext("c") subject.onCompleted() }
打印结果:
— BehaviorSubject example —
Subscription: 1, event: Next(z) —-最近没有则发送了默认值”z”
Subscription: 1, event: Next(a)
Subscription: 1, event: Next(b)
Subscription: 2, event: Next(b) —-最近发送的是”b”则在订阅时发送了一条”b”
Subscription: 1, event: Next(c)
Subscription: 2, event: Next(c)
Subscription: 1, event: Completed
Subscription: 2, event: Completed
Variable
variable 类似于 BehaviorSubject 不同之处在于variable不可以主动发送.Completed 和.Error事件, 他会自动判断订阅结束之后发送.Completed事件
example("Variable") { let variable = Variable("z") self.writeSequenceToConsole("1", squence: variable.asObservable()) variable.value = "a" variable.value = "b" self.writeSequenceToConsole("2", squence: variable.asObservable()) variable.value = "c" }
打印结果:
— Variable example —
Subscription: 1, event: Next(z)
Subscription: 1, event: Next(a)
Subscription: 1, event: Next(b)
Subscription: 2, event: Next(b)
Subscription: 1, event: Next(c)
Subscription: 2, event: Next(c)
Subscription: 1, event: Completed
Subscription: 2, event: Completed
function
map
map 是对每一个元素进行改变, 相当于把信号内容 更改成其他内容
example("map") { let originalSequence = Observable.of(1, 2, 3) _ = originalSequence .map{$0 * 2} // 对原有数据进行修改 .subscribe{ print($0)} }
打印结果
— map example —
Next(2)
Next(4)
Next(6)
Completed
FlatMap
Map一般用于对原始的参数进行加工处理,返回值还是基本的类型,可以在subscribe中使用(适用)的类型。
flatMap一般用于输出一个Observable,而其随后的subscribe中的参数也跟Observable中的参数一样,注意不是Observable,一般用于对原始数据返回一个Observable,这个Observable中数据类型可以是原来的,也可以是其他的
example("flatMap") { () -> () in let sequenceInt = Observable.of(1, 2, 3) let sequenceString = Observable.of("A", "B", "--") _ = sequenceInt.flatMap{ (x:Int) -> Observable<String> in return sequenceString }.subscribe{ print($0) } }
打印结果
可以看出 flatmap把每一个信号都转换成一个新的Observable
— flatMap example —
Next(A)
Next(B)
Next(–)
Next(A)
Next(B)
Next(–)
Next(A)
Next(B)
Next(–)
Completed
Scan
scan 是遍历源Observable 中的每一个元素 然后根据一定的计算 组合出新的元素 然后把每次计算的结果再发送出来
注意 accumulator的第一个元素为上一次计算的结果
example("scan") { () -> () in let sequenceToSum = Observable.of(0,1,2,3,4,5) _ = sequenceToSum.scan(100, accumulator: { a, b in // a为上次组合出来的数据 100 为 首次的数据 a + b }).subscribe{ print($0) } }
打印结果
— scan example —
Next(100)
Next(101)
Next(103)
Next(106)
Next(110)
Next(115)
Completed
Filter
filter 是把通过一定的比较方法 来判断Observable发送的信号是否符合要求, 再把符合要求的发送出去, filter方法的返回值为bool
// 过滤 example("filter") { () -> () in let subscription = Observable.of(0,1,2,3,4,5,6,7,8,9) _ = subscription.filter({ $0 % 2 == 0 }).subscribe { print($0) } }
打印结果
— filter example —
Next(0)
Next(2)
Next(4)
Next(6)
Next(8)
Completed
DistinctUntilChanged
distinctUntilChanged 用来过滤掉数据中连续重复的数据
注意是连续重复的!
example("distinctUntilChanged") { _ = Observable.of(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 4) .distinctUntilChanged() .subscribe { print($0) } }
打印结果
— distinctUntilChanged example —
Next(1)
Next(2)
Next(3)
Next(1)
Next(4)
Completed
Take
take 是只把一定量的数据发送出去, 多余的不会发送
example("take") { () -> () in let subscription = Observable.of(1, 2, 3, 4, 5, 6) _ = subscription // 这里的3 就代表了 只取前三个数据 .take(3) .subscribe({ (event) -> Void in print(event) }) }
打印结果
— take example —
Next(1)
Next(2)
Next(3)
Completed
Combining
CombineLatest操作符把两个Observable产生的结果进行合并,合并的结果组成一个新的Observable,这两个Observable中任意一个Observable产生的结果,都和另一个Observable最后产生的结果,按照一定的规则进行合并
结果跟多个observable的顺序有关
example("Combining") { () -> () in let sub1 = Observable.of(1, 2) let sub2 = Observable.of("a", "b", "c", "d", "e", "f") let sub3 = Observable.of("!", "@", "#", "$", "^", "&") _ = Observable.combineLatest(sub1, sub2, sub3) { a, b, c in "\(a)" + b + c }.subscribe { print($0) } }
打印结果
— Combining example —
Next(2f!)
Next(2f@)
Next(2f#)
Next(2f$)
Next(2f^)
Next(2f&)
Completed
StartWith
startwith 可以给一个Observable 在开始时插入一条数据
example("startWith") { _ = Observable.of(4, 5, 6, 7, 8, 9)// .startWith(3)// .startWith(2)// .startWith(1) .startWith(0) .subscribe { print($0) } }
打印结果
— startWith example —
Next(0)
Next(4)
Next(5)
Next(6)
Next(7)
Next(8)
Next(9)
Completed
Zip
顾名思义就是压缩的意思
zip会把多个信号(最多8个)进行一对一的, 按顺序组合, 而且必须多个信号都同时有值得时候才可以组合
example("zip") { let intOb1 = Observable.of(0, 1) let intOb2 = Observable.of(0, 1, 2, 3) let intOb3 = Observable.of(0, 1, 2, 3, 4) _ = Observable.zip(intOb1, intOb2, intOb3) { ($0 + $1) * $2 } .subscribe { print($0) } }
打印结果
可以看出 结果中 只有三组信号中 第0位和第一位的组合, 其余的只要少了一个信号 都不会组合成功
— zip example —
Next(0)
Next(2)
Completed
Merge
merge 和 Combining不同 他是把组合的几组Observable按接收的顺序 一个一个发送出来
example("merge 1") { let subject1 = PublishSubject<Int>() let subject2 = PublishSubject<Int>() _ = Observable.of(subject1, subject2) .merge() .subscribeNext { int in print(int) } subject1.on(.Next(20)) subject1.on(.Next(40)) subject1.on(.Next(60)) subject2.on(.Next(1)) subject1.on(.Next(80)) subject1.on(.Next(100)) subject2.on(.Next(1)) }
打印结果
— merge 1 example —
Next(20)
Next(40)
Next(60)
Next(1)
Next(80)
Next(100)
Next(1)
merge还可以添加一个参数”maxConcurrent” 这个是控制操作的Observable个数
example("merge 2") { let subject1 = PublishSubject<Int>() let subject2 = PublishSubject<Int>() let subject3 = PublishSubject<Int>() _ = Observable.of(subject1, subject2, subject3) .merge(maxConcurrent: 2) // 默认 操作个数 2 的意思是 只subject1和subject2 .subscribe { print($0) } subject1.on(.Next(20)) subject1.on(.Next(40)) subject1.on(.Next(60)) subject2.on(.Next(1)) subject1.on(.Next(80)) subject1.on(.Next(100)) subject2.on(.Next(1)) subject3.on(.Next(12312312)) }
打印结果
— merge 2 example —
Next(20)
Next(40)
Next(60)
Next(1)
Next(80)
Next(100)
Next(1)
SwitchLatest
switchLatest是将一个Observable
example("switchLatest") { let var1 = Variable(0) let var2 = Variable(200) // 这里的var3就是一个Observable<Observable<Int>> let var3 = Variable(var1.asObservable()) let d = var3 .asObservable() .switchLatest() // 返回 (self.element as Observable).element 并 只返回最新数据 .subscribe { print($0) } var1.value = 1 var1.value = 2 var1.value = 3 var1.value = 4// var1的每一次改变 var3都会输出最新结果 // 当var3 的值切换成另一个Observable时也会输出切换后的最新结果 var3.value = var2.asObservable() var2.value = 201 // 同理改变var1 var1.value = 5 var1.value = 6 var1.value = 7 // 因为var3已经把值切换成了var2 所以var1 的改变 不会影响var3 }
打印结果
— switchLatest example —
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(200)
Next(201)
Completed
CatchError
catcherror 跟flatmap 有点像 不过 catcherror只能改变出错时的信号 然后进行输出
example("catchError") { () -> () in let sequenceThatFails = PublishSubject<Int>() let recoverySequence = Observable.of(100, 200, 300, 400) _ = sequenceThatFails // 当有错误时 对错误进行解析 然后进行正确操作 .catchError({ (error) -> Observable<Int> in return recoverySequence }) // 如果解决错误的方法相对简单 可以用下边的方法直接返回一个默认值 // .catchErrorJustReturn(100) .subscribe { print($0) } sequenceThatFails.onNext(1) sequenceThatFails.onNext(2) // 发送一个错误 sequenceThatFails.onError(NSError(domain: "错误了", code: 100, userInfo: nil)) }
打印结果
— catchError example —
Next(1)
Next(2)
Next(100)
Next(200)
Next(300)
Next(400)
Completed
Retry
意思就是 在出现错误的时候 通过重新订阅妄图解决错误 -.-!!
不过如果解决不了 就会形成死循环….
example("retry") { var count = 1 // bad practice, only for example purposes let funnyLookingSequence = Observable<Int>.create { observer in let error = NSError(domain: "Test", code: 0, userInfo: nil) observer.on(.Next(0)) observer.on(.Next(1)) observer.on(.Next(2)) if count < 2 { observer.on(.Error(error)) count += 1 } observer.on(.Next(3)) observer.on(.Next(4)) observer.on(.Next(5)) observer.on(.Completed) return NopDisposable.instance } _ = funnyLookingSequence .retry() .subscribe { print($0) } }
打印结果
— retry example —
Next(0)
Next(1)
Next(2)
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Completed
Subscribe
这个想必你已经了解了 就是订阅, 所有的信号必须通过订阅来进行下一步动作
普通的subscribe 是可以订阅任何类型
有普通就有个别
1, subscribeNext 只订阅next类型事件
2, subscribeCompleted 只订阅complete事件
3, subscribeError 只订阅error事件
这个就不给实例了 上边有的是 ^_^
DoOn
doon是在执行subscript执行之前 插入一条任务,
doon和subscript 有点类似 也有普通形式 和 next, complete , error三种形式
example("doOn") { let sequenceOfInts = PublishSubject<Int>() _ = sequenceOfInts .doOn { print("Intercepted event \($0)") } .subscribe { print($0) } sequenceOfInts.on(.Next(1)) sequenceOfInts.on(.Completed) }
打印结果
— doOn example —
Intercepted event Next(1)
Next(1)
Intercepted event Completed
Completed
Take
take分为takeUntile 和takeWhile
takeUntile 是根据另一条Observable 来终止当前Observable的订阅
example("takeUntil") { let originalSequence = PublishSubject<Int>() let whenThisSendsNextWorldStops = PublishSubject<Int>() _ = originalSequence .takeUntil(whenThisSendsNextWorldStops) .subscribe { print($0) } originalSequence.on(.Next(1)) originalSequence.on(.Next(2)) originalSequence.on(.Next(3)) originalSequence.on(.Next(4)) whenThisSendsNextWorldStops.on(.Next(1)) originalSequence.on(.Next(5)) }
打印结果
— takeUntil example —
Next(1)
Next(2)
Next(3)
Next(4)
Completed
takeWhile 是根据一个条件来终止当前的OBservable的订阅
example("takeWhile") { let sequence = PublishSubject<Int>() _ = sequence .takeWhile { int in int < 4 } .subscribe { print($0) } sequence.on(.Next(1)) sequence.on(.Next(2)) sequence.on(.Next(3)) sequence.on(.Next(4)) sequence.on(.Next(5)) }
打印结果
— takeWhile example —
Next(1)
Next(2)
Next(3)
Completed
Concat
concat 可以合并一系列的信号
example("concat") { let var1 = BehaviorSubject(value: 0) let var2 = BehaviorSubject(value: 200) // var3 is like an Observable<Observable<Int>> // 把var3的值设置为var1 let var3 = BehaviorSubject(value: var1) let d = var3 .concat() .subscribe { print($0) } var1.on(.Next(1)) var1.on(.Next(2)) var1.on(.Next(3)) var1.on(.Next(4)) // var1改变以后就会使var3的订阅者接收到信息 var3.on(.Next(var2)) // 把var3的值修改为var2 var2.on(.Next(20010)) // 再completed之前 可以改变初始值 var2.on(.Next(2343242)) var1.on(.Next(5)) var1.on(.Next(6)) var1.on(.Next(7)) var1.on(.Completed) var2.on(.Next(202)) var2.on(.Next(203)) var2.on(.Next(204)) }
打印结果
— concat example —
Next(0) // 订阅的同时就会得到初始值
Next(1)
Next(2)
Next(3)
Next(4)
// 这个时候把var3的值修改为var2
Next(5)
Next(6)
Next(7)// 但在var1没有发送complete之前 var3还是会相应var1的改变
Next(2343242) // 在var1发送了complete之后 var3 立刻收到了 var2的初始值
Next(202)
Next(203)
Next(204)// 以此类推
reduce
类似sacn
example("reduce") { _ = Observable.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) .reduce(0, accumulator: { (a, b) -> Int in print(a) return a + b }) .subscribe { print($0) } }
打印结果
— reduce example —
0
0
1
3
6
10
15
21
28
36
Next(45)
Completed
总结
到现在 基本的语法 大概就是这些 还有一些 零零散散的 可以在官方的RXplayground中查看,
重点其实是在与运用, 随后我会发一些关于实际应用的文章, 敬请期待…
- RxSwift 教程 学习
- RxSwift使用教程
- RxSwift使用教程
- RxSwift使用教程
- RxSwift 学习指导索引
- moya+RxSwift+HandyJSON 学习
- 初识RxSwift及使用教程
- RxSwift
- RxSwift
- RxSwift
- RxSwift
- RxSwift
- RxSwift
- RxSwift
- RxSwift
- RxSwift使用教程大全 韩俊强的博客
- 自主学习之RxSwift(一) -----Driver
- 自主学习之RxSwift(二) -----flatMap
- eclipse 测试java项目基础
- mysql数据库 DB类
- 5-19 支票面额 (15分)
- Android MTK 打开相机提示 Connect not to Camera
- 79. Word Search 回溯算法
- RxSwift 教程 学习
- shell的变量功能
- php之变量
- 懒加载的解决
- android开发中爬过的坑
- 遗传算法入门(连载之六)
- 如何在MySQL的不指定列名称的前提下插入一整行数据
- [LeetCode28] Implement strStr()
- 神经网络的严冬与复兴之路