RxSwift 调度者-scheduler(二)

875 阅读3分钟

RxSwift篇章

一:案例

代码

        let ob = Observable.of(1, 2, 3, 4, 5, 6)
        ob.observeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
            .subscribe{
                print("observeOn",$0,Thread.current)
        }
        .disposed(by: disposeBag)

问题:

  • observeOn的作用?
  • 订阅打印的线程?
  • 调度逻辑?

二:源码分析

源序列

  • 点击of进入
  • 源序列为ObservableSequence类型, scheduler为CurrentThreadScheduler.
    public static func of(_ elements: Element ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable<Element> {
        return ObservableSequence(elements: elements, scheduler: scheduler)
    }

observeOn

  • 点击observeOn进入
  • 中间层序列为ObserveOnSerialDispatchQueue, scheduler为 SerialDispatchQueueScheduler.
public func observeOn(_ scheduler: ImmediateSchedulerType)
        -> Observable<Element> {
            if let scheduler = scheduler as? SerialDispatchQueueScheduler {
                return ObserveOnSerialDispatchQueue(source: self.asObservable(), scheduler: scheduler)
            }
            else {
                return ObserveOn(source: self.asObservable(), scheduler: scheduler)
            }
    }

订阅流程

  • 简化流程中的常规部分,只关注重点.
  • 中间层序列订阅开始, 开始调度,观察者传递开始.
  • 中间层序列self.run,内部开始源序列的订阅.
//中间层序列订阅
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
        ...
        }
        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
            }
        }
    }
//源序列的订阅
    override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
        let sink = ObserveOnSerialDispatchQueueSink(scheduler: self.scheduler, observer: observer, cancel: cancel)
        let subscription = self.source.subscribe(sink)
        return (sink: sink, subscription: subscription)
    }
  • 源序列run()
    func run() -> Disposable {
        return self._parent._scheduler.scheduleRecursive(self._parent._elements.makeIterator()) { iterator, recurse in
            var mutableIterator = iterator
            if let next = mutableIterator.next() {
                self.forwardOn(.next(next))
                recurse(mutableIterator)
            }
            else {
                self.forwardOn(.completed)
                self.dispose()
            }
        }
    }
  • 重点self._parent._scheduler.scheduleRecursive(),其闭包为源序列的信号处理,递归调用.
        public func scheduleRecursive<State>(_ state: State, action: @escaping (_ state: State, _ recurse: (State) -> Void) -> Void) -> Disposable {
        let recursiveScheduler = RecursiveImmediateScheduler(action: action, scheduler: self)
        recursiveScheduler.schedule(state)
        return Disposables.create(with: recursiveScheduler.dispose)
    }
  • RecursiveImmediateScheduler的初始化,保存源序列的信号处理.
  • 重点schedule(state)函数
    func schedule(_ state: State) {
        var scheduleState: ScheduleState = .initial
        let d = self._scheduler.schedule(state) { state -> Disposable in
            // best effort
            if self._group.isDisposed {
                return Disposables.create()
            }
            let action = self._lock.calculateLocked { () -> Action? in
                switch scheduleState {
                case let .added(removeKey):
                    self._group.remove(for: removeKey)
                case .initial:
                    break
                case .done:
                    break
                scheduleState = .done
                return self._action
            }
            if let action = action {
                action(state, self.schedule)
            }
            return Disposables.create()
        ...
    }

  • 进入schedule调度.(源序列调度,信号进入队列)
    public func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        if CurrentThreadScheduler.isScheduleRequired {
            CurrentThreadScheduler.isScheduleRequired = false
            /// 源序列订阅
            let disposable = action(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
    }
}
  • 将传入的闭包参数包装为ScheduledItem.
  • ScheduledItem入栈: queue.value.enqueue(scheduledItem)
  • 流程继续至中间序列调度(信号从队列取出)
  • let latest = queue.value.dequeue() = queue.value.dequeue()
  • 重点latest.invoke(), 其中last为我们存入的ScheduledItem.
    func invoke() {
         self._disposable.setDisposable(self._action(self._state))
    }
  • 重点self._action(self._state),这个闭包运行,回到源序列递归处理RecursiveImmediateScheduler
let d = self._scheduler.schedule(state) { state -> Disposable in
            // best effort
            if self._group.isDisposed {
                return Disposables.create()
            }
            let action = self._lock.calculateLocked { () -> Action? in
                switch scheduleState {
                case let .added(removeKey):
                    self._group.remove(for: removeKey)
                case .initial:
                    break
                case .done:
                    break
                scheduleState = .done
                return self._action
            }
            if let action = action {
                action(state, self.schedule)
            }
            return Disposables.create()
            ...

*重点 action(state, self.schedule) 回调源序列递归调度.

    func run() -> Disposable {
        return self._parent._scheduler.scheduleRecursive(self._parent._elements.makeIterator()) { iterator, recurse in
            var mutableIterator = iterator
            if let next = mutableIterator.next() {
                self.forwardOn(.next(next))
                recurse(mutableIterator)
            }
            else {
                self.forwardOn(.completed)
                self.dispose()
            }
        }
    }
  • self.forwardOn(.next(next))传递信号到中间层序列的sink, 常规流程.
//ObserveOnSerialDispatchQueueSink

        self.cachedScheduleLambda = { pair in
            guard !cancel.isDisposed else { return Disposables.create() }

            pair.sink.observer.on(pair.event)

            if pair.event.isStopEvent {
                pair.sink.dispose()
            }

            return Disposables.create()
        }
    //开始信号处理
    override func onCore(_ event: Event<Element>) {
        _ = self.scheduler.schedule((self, event), action: self.cachedScheduleLambda!)
    }
    //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)
    }
    //
    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
    }
  • onCore函数开始信号处理.

  • 很明显这里的self.scheduler.schedule,处理线程,因为我们设置了自定义的线程.

  • 线程处理的流程至self.queue.async,其中action(state)运行,传入的action为cachedScheduleLambda.

  • pair.sink.observer.on(pair.event) 将信号传递给observer,订阅实现.

总结:

observeOn的作用?

  • 中间层序列,内部保存源序列和scheduler.
  • 开启源序列的订阅
  • 对应sink处理接收到的源序列信号,保证在scheduler线程环境下继续进行信号传递.

订阅打印的线程?

  • 线程为我们在源序列ob.observeOn时设置的线程.

调度逻辑?

  • 中间层序列创建

  • 调度环境&观察者传递准备

  • 源序列订阅 -> 调度环境调度 -> 流程到观察者就是我们中间内部序列的Sink

  • Sink -> 调度执行 -> 响应发给观察者

  • 由观察者响应订阅事件event