subscribeOn指定 Observable 在那个 Scheduler 执行
下面让我们一起来看一下subscribeOn内部是如何实现的
先来看一段简单的代码
Observable.of(1,2,3,4,5)
.subscribeOn(SerialDispatchQueueScheduler.init(internalSerialQueueName: "subscribeOnSerial"))
.subscribe{print("subscribeOn",$0,Thread.current)}
.disposed(by: self.bag)
一句一句来解析:
-
(一)Observable.of(1,2,3,4,5)
public static func of(_ elements: Element ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable<Element> {
return ObservableSequence(elements: elements, scheduler: scheduler)
}
这段代码会要求我们传入一些元素,然后会给一个默认的scheduler:CurrentThreadScheduler 会返回一个ObservableSequence类型的序列
final private class ObservableSequence<Sequence: Swift.Sequence>: Producer<Sequence.Element> {
fileprivate let _elements: Sequence
fileprivate let _scheduler: ImmediateSchedulerType
init(elements: Sequence, scheduler: ImmediateSchedulerType) {
self._elements = elements//1 2 3 4 5
self._scheduler = scheduler//<CurrentThreadScheduler: 0x60000255c010>
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = ObservableSequenceSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
}
该序列初始化时保存了原序列(elements) 和 调度环境(scheduler),并继承了Producer,实现了run方法。
-
(二).subscribeOn(SerialDispatchQueueScheduler.init(internalSerialQueueName: "subscribeOnSerial"))
public class SerialDispatchQueueScheduler : SchedulerType {
let configuration: DispatchQueueConfiguration
init(serialQueue: DispatchQueue, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) {
self.configuration = DispatchQueueConfiguration(queue: serialQueue, leeway: leeway)
}
public convenience init(internalSerialQueueName: String, serialQueueConfiguration: ((DispatchQueue) -> Void)? = nil, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) {
let queue = DispatchQueue(label: internalSerialQueueName, attributes: [])
serialQueueConfiguration?(queue)
self.init(serialQueue: queue, leeway: leeway)
}
}
使用便利构造器初始化一个串行队列,并调用
self.init将队列queue和 延迟时间leeway保存在self.configuration中。 接下来,会带着创建好的队列来到SubscribeOn函数:
final private class SubscribeOn<Ob: ObservableType>: Producer<Ob.Element> {
let source: Ob
let scheduler: ImmediateSchedulerType
init(source: Ob, scheduler: ImmediateSchedulerType) {
self.source = source//<ObservableSequence<Array<Int>>: 0x6000032da2c0>
self.scheduler = scheduler//<SerialDispatchQueueScheduler: 0x6000029d9140>
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Ob.Element {
let sink = SubscribeOnSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
}
SubscribeOn在初始化的时候保存了源函数(Observable.of(1,2,3,4,5))和我们初始化的串行队列(SerialDispatchQueueScheduler),并且同样继承了Producer,实现了自己的run方法。
-
(三).subscribe{print("subscribeOn",$0,Thread.current)}
由于SubscribeOn继承Producer,所以回来到Producer的subscribe
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
if !CurrentThreadScheduler.isScheduleRequired {
// The returned disposable needs to release all references once it was disposed.
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
else {
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
}
由于当前线程没有被绑定,所以走else的方法,会携带闭包来到当前线程的schedule方法。
public func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
if CurrentThreadScheduler.isScheduleRequired {
CurrentThreadScheduler.isScheduleRequired = false//绑定线程
let disposable = action(state)//state 外界闭包
defer {//延迟执行
CurrentThreadScheduler.isScheduleRequired = true
CurrentThreadScheduler.queue = nil
}
guard let queue = CurrentThreadScheduler.queue else {
return disposable
}
while let latest = queue.value.dequeue() {
if latest.isDisposed {
continue
}
latest.invoke()
}
return disposable
}
let existingQueue = CurrentThreadScheduler.queue
let queue: RxMutableBox<Queue<ScheduledItemType>>
if let existingQueue = existingQueue {//当前线程存在队列
queue = existingQueue
}
else {//当前线程不存在队列,初始化一个
queue = RxMutableBox(Queue<ScheduledItemType>(capacity: 1))
CurrentThreadScheduler.queue = queue
}
let scheduledItem = ScheduledItem(action: action, state: state)
queue.value.enqueue(scheduledItem)
return scheduledItem
}
这个方法先绑定了当前线程,然后回去执行
schedule方法带过来的外界闭包
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
然后 sink.run 又回到了SubscribeOn的run方法中
final private class SubscribeOn<Ob: ObservableType>: Producer<Ob.Element> {
let source: Ob
let scheduler: ImmediateSchedulerType
init(source: Ob, scheduler: ImmediateSchedulerType) {
self.source = source//<ObservableSequence<Array<Int>>: 0x6000032da2c0>
self.scheduler = scheduler//<SerialDispatchQueueScheduler: 0x6000029d9140>
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Ob.Element {
let sink = SubscribeOnSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
}
然后会SubscribeOnSink的初始化方法,然后走run方法
final private class SubscribeOnSink<Ob: ObservableType, Observer: ObserverType>: Sink<Observer>, ObserverType where Ob.Element == Observer.Element {
typealias Element = Observer.Element
typealias Parent = SubscribeOn<Ob>
let parent: Parent
init(parent: Parent, observer: Observer, cancel: Cancelable) {
self.parent = parent//<SubscribeOn<Observable<Int>>: 0x6000032dabc0>
super.init(observer: observer, cancel: cancel)//on赋值会来到下面的on方法
}
func on(_ event: Event<Element>) {
self.forwardOn(event)
if event.isStopEvent {
self.dispose()
}
}
func run() -> Disposable {
let disposeEverything = SerialDisposable()
let cancelSchedule = SingleAssignmentDisposable()
disposeEverything.disposable = cancelSchedule
//self.parent.scheduler <SerialDispatchQueueScheduler: 0x6000029d9140>
let disposeSchedule = self.parent.scheduler.schedule(()) { _ -> Disposable in
let subscription = self.parent.source.subscribe(self)
disposeEverything.disposable = ScheduledDisposable(scheduler: self.parent.scheduler, disposable: subscription)
return Disposables.create()
}
cancelSchedule.setDisposable(disposeSchedule)
return disposeEverything
}
}
self.parent.scheduler.schedule为SerialDispatchQueueScheduler,携带闭包来到SerialDispatchQueueScheduler的schedule方法。
public final func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
return self.scheduleInternal(state, action: action)
}
func scheduleInternal<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
return self.configuration.schedule(state, action: action)
}
接下来会带着一开始初始化串行队列给self.configuration赋值时保存的队列和延迟时间来到configuration的schedule方法。
func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
let cancel = SingleAssignmentDisposable()
self.queue.async {
if cancel.isDisposed {
return
}
cancel.setDisposable(action(state))
}
return cancel
}
会看到我们初始化队列,异步执行外界闭包
let disposeSchedule = self.parent.scheduler.schedule(()) { _ -> Disposable in
let subscription = self.parent.source.subscribe(self)
disposeEverything.disposable = ScheduledDisposable(scheduler: self.parent.scheduler, disposable: subscription)
return Disposables.create()
}
self.parent.source.subscribe(self)会由源序列来订阅当前的sink,看到这里我们就知道了,源序列在我们特定的队列中进行订阅。
总结
subscribeOn为我们创建一个中间层序列subscribeOn,然后并没有SubscribeOn函数的run方法中直接进行源序列的订阅,而是在SubscribeOnSink的run方法中保证了源序列在特定线程中的订阅。