Observable
简介
Observable也是一个序列,其核心就是异步操作
Observable的生命周期:
Observable发射包含元素的事件- 它可以一直发射事件直到终止事件发生,比如发射完成信号或者错误信号
- 一旦序列被终止了,它就不能再发射任何事件了
其中事件Event在源码中是被包装成枚举
“/// Represents a sequence event.
///
/// Sequence grammar:
/// **next\* (error | completed)**
public enum Event<Element> {
/// Next element is produced.
case next(Element)
/// Sequence terminated with an error.
case error(Swift.Error)
/// Sequence completed successfully.
case completed
}”
Observable的快速创建方法
just
just将传入的item转化为发射item的Observable
just有些类似于from,但是from会深入数组、迭代器或者类似的对象中将其中的内容作为要发射的item提取出来,而just只是简单的发射你传入的item
注意,如果你将null传递给just,它将返回一个发出null作为item的Observable。不要错误地认为这将返回一个空的可观察对象(一个根本不发出任何item的对象)
let one = 1
let two = 2
let three = 3
let observable = Observable<Int>.just(one)
observable.subscribe { event in
print(event)
}.disposed(by: disposeBag)
----打印结果-----
next(1)
completed
of
of可以传多个同类型参数
let observable2 = Observable.of(one, two, three)
observable2.subscribe { event in
print(event)
}.disposed(by: disposeBag)
----打印结果-----
next(1)
next(2)
next(3)
completed
let observable3 = Observable.of([one, two, three], ["12333"])
observable3.subscribe { element in
print(element)
}
onCompleted: {
print("完成")
}
onDisposed: {
print("observable3 disposed")
}.disposed(by: disposeBag)
----打印结果-----
[1, 2, 3]
["12333"]
完成
observable3 disposed
from
from将各种其他对象和数据类型转换为 Observable
当你使用可观察对象时,如果你想要使用的所有数据都可以表示为可观察对象,而不是可观察对象和其他类型的混合,这样会更方便。这允许你使用一组操作符来管理数据流的整个生命周期。通过明确的转换一些对象将它们变为可观察的,你将允许它们与其它可观察对象进行平等的交互。
出于这个原因,大多数ReactiveX实现都有允许你将某些特定于语言的对象和数据结构转换为Observables的方法
例如,可迭代对象可以被认为是一种同步的可观察对象;未来作为一种总是发射单个item的可观察对象
let observable4 = Observable.from([one, two, three])
observable4.subscribe { event in
print(event)
}.disposed(by: disposeBag)
----打印结果-----
next(1)
next(2)
next(3)
completed
总结:
just仅支持单个参数传递,而且传递什么订阅后便得到什么of可以传递多个同类型的参数,同样也是传递什么订阅后便得到什么from传递数组,但是它会将数组中的元素拿出来
empty
//empty没有类型能推断,所以必须显示的写明void
let observable = Observable<Void>.empty()
observable.subscribe { _ in
print("next")
} onError: { error in
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
----打印结果-----
完成
disposed
如果你想得到一个立即终止或者你有意想要0个值的可观察队列,你就可以使用empty
never
与empty不同,never创建的可观察序列不会发出任何信号,也不会终止。它可以用来表示无限的持续时间
let observable = Observable<Void>.never()
observable.subscribe { e in
print(e)
} onError: { error in
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
----打印结果-----
结果是没有任何打印,甚至连完成和销毁也没有打印,所以如何知道这个队列还在运行??
Observable的源码分析
序列的三步:
创建订阅销毁
let ob = Observable<Any>.create { observer in
observer.onNext("12345")
observer.onCompleted()
return Disposables.create()
}
ob.subscribe { text in
print("订阅到了\(text)")
} onError: { error **in**
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("销毁")
}.disposed(by: disposedBag)
---打印结果---
订阅到了12345
完成
销毁
从上面代码结果来分析很明显应当是在订阅后即subscribe的回调中先执行了上面create方法的回调,因为create方法的回调中是发送信号,只有先发送了信号在订阅中才能收到信号,但是来看到源码里
在create中仅仅创建了一个AnonymousObservable对象并且将回调当做参数发给了它
AnonymousObservable继承于Producer
在初始化方法中也仅仅是将收到的参数也就是上一步的闭包保存了而已
在create中没找到相关线索,接下来先看看subscribe方法
可以看到这里内部主要生成一个AnonymousObserver类型的observer对象,这里同样是将尾随闭包存放于内部
最主要的是底下self.asObservable().subscribe(observer)这里self是AnonymousObservable,刚说过它继承于Producer,在调用subscribe方法的时候,其实是调用其父类也就是Producer的subscribe方法
这里会执行else的分支代码,重点在self.run这里,self是AnonymousObservable,所以会调用自己的run方法
会调用sink.run也就是AnonymousObservableSink的run方法
这里run方法内的调用parent就是AnonymousObservable对象,这里就是直接调用了之前保存的回调,也就是最开始创建信号create方法后面的尾随闭包,直接调用了这个闭包
Observable核心图解如下:
Observable类分析
刚才分析了AnonymousObservable发现它的父类是Producer,而Producer的父类是Observable,Observable是整个链条的基类,它只是要遵循ObservableType协议
ObservableType协议中有方法subscribe,也就是说只要遵从这个协议的对象都可以进行订阅,但是如果不是属于这个继承链的对象虽然也可以调用订阅方法,但是最好还是使用asObservable先转换为Observable为好
例如下面代码这样写也不会报错,但是最好不要这么写
UISwitch().rx.value.subscribe { event in
print(event)
}.disposed(by: disposedBag)
先使用asObservable转化后再订阅
UISwitch().rx.value.asObservable().subscribe { event in
print(event)
}.disposed(by: disposedBag)
这里的asObservable()是原先的ControlProperty类型的value转变为Observable的类型