RxSwift: Schedulers details, rxswiftschedulers
Scheduler
In short, Scheduler is the context of process execution (or the context of program execution ). Context can be a thread, a dispatch queue, or NSOperation in OperationQueueScheduler. Here is a good example of how the dispatcher is used:
We can see that we may make network requests in the backend Scheduler and then cache data. And pass the data to all subscribers. Most of the time, it will return to MainScheduler, where MainScheduler is located at the top of the main thread. The UI update operation must be performed in the main thread. So it will switch to MainScheduler. Note: The Scheduler is not a thread.
Embedded Scheduler (Builtin schedulers)
CurrentThreadScheduler (Serial sched)
The scheduler of the current thread. This is also the default scheduler used to generate elements.
MainScheduler (Serial sched)
MainScheduler is a part of the main thread. This scheduler is often used to handle user interface changes (that is, to execute UI work) and execute some high-priority tasks. Long tasks should not be executed in the scheduler, such as requests for data from the server and other heavy tasks. In addition, if you run side effects to update the UI, you must convert it to MainScheduler to ensure that the screen UI is updated successfully. MainScheduler is also used to execute all calculations. When using Units and Driver. The Driver ensures that the computation is often executed in MainScheduler, allowing you to directly bind data to the user interface. The following are some source code of the MainScheduler class:
public final class MainScheduler : SerialDispatchQueueScheduler { private let _mainQueue: DispatchQueue /// Initializes new instance of `MainScheduler`. public init() { _mainQueue = DispatchQueue.main super.init(serialQueue: _mainQueue) } /// Singleton instance of `MainScheduler` public static let instance = MainScheduler()}
The code above shows that mainschedue inherits from SerialDispatchQueueScheduler, has an instance Singleton, and specifies the running thread as the main thread (DispatchQueue. main), we often use MainScheduler. instance to obtain the main thread and use it with the observeOn operator.
SerialDispatchQueueScheduler (Serial scheduler)
Serialdispatchqueueschedue manages the abstract work of the serial DispatchQueue. It will ensure that even concurrent dispatch queues (concurrent dispatch queue ?) It will also be converted to serial. When using the observeOn operator, this scheduler has several significant advantages. You can use this scheduler to process Background tasks and use serial methods for better execution. For example, if you have an application that communicates with the server (as in a Firebase or GraphQL application), you may want to avoid distributing multiple and simultaneous requests, this puts too much pressure on the server. The scheduler completes your work just like a serial task queue and runs in order.
ConcurrentDispatchQueueScheduler (Concurrent scheduler)
Concurrentdispatchqueuesched is similar to SerialDispatchQueueScheduler, which is used to manage DispatchQueue abstraction. The main difference is that this is not a serial queue, but a concurrent queue. When using observeOn, this scheduler is not the best choice. ConcurrentDispatchQueueScheduler is the first choice for multitasking, time-consuming, and synchronous task execution.
OperationQueueScheduler (Concurrent scheduler)
Operationqueueschedue is very similar to ConcurrentDispatchQueueScheduler, but not working with DispatchQueue, but working with NSOperationQueue. Sometimes, you need more concurrency control permissions, but you cannot perform operations in ConcurrentDispatchQueueScheduler. You can choose OperationQueueScheduler.
OperationQueueScheduler is a good choice if you need to set the maximum number of concurrent jobs. Because you can use maxConcurrentOperationCount to set the maximum number of operations
TestScheduler
It is very special, it is used for testing, so note that it cannot be used in normal development, it should only be used for testing, it is part of the RxTest library.
Note: The interesting thing is that if the concurrent queue is passed to the serial sched, RxSwift will ensure that the concurrent queues are changed to the serial queue ). Similarly, if a serial queue is passed to the concurrent dispatcher, the serial queue is also converted into a concurrent queue)
Switching schedulers)
One of the most important tasks in rx is the ability to switch schedulers at any time ). There are no restrictions except an imposed event generated by an internal process.
There are two main operators in the thread section: observeOn? And? SubscribeOn ?, Commonly used? ObserveOn. ObserveOn is a method in the ObservableType extension:
extension ObservableType { /** Wraps the source sequence in order to run its observer callbacks on the specified scheduler. This only invokes observer callbacks on a `scheduler`. In case the subscription and/or unsubscription actions have side-effects that require to be run on a scheduler, use `subscribeOn`. - seealso: [observeOn operator on reactivex.io](http://reactivex.io/documentation/operators/observeon.html) - parameter scheduler: Scheduler to notify observers on. - returns: The source sequence whose observations happen on the specified scheduler. */ public func observeOn(_ scheduler: ImmediateSchedulerType) -> RxSwift.Observable
}
Call? ObserveOn? Specify the thread in which the next operation is located. You can also understand the schedable where the next operation listens to the Observable. A typical example: Initiate a network request in the background, parse the data, and refresh the page in the main thread. We can first use subscribeOn to switch to the background to send a request and parse the data, and then use observeOn to switch back to the main thread Update page. Or use observeOn twice.
sequence1 .observeOn(backgroundScheduler) .map { n in print("This is performed on the background scheduler") } .observeOn(MainScheduler.instance) .map { n in print("This is performed on the main scheduler") }
Call? SubscribeOn? Determines the thread in which the subscriber's operations are performed. For subscribeOn:
extension ObservableType { /** Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used. This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer callbacks on a `scheduler`, use `observeOn`. - seealso: [subscribeOn operator on reactivex.io](http://reactivex.io/documentation/operators/subscribeon.html) - parameter scheduler: Scheduler to perform subscription and unsubscription actions on. - returns: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. */ public func subscribeOn(_ scheduler: ImmediateSchedulerType) -> RxSwift.Observable
}
Of course, if we do not explicitly call these two operations, the subsequent operations will be executed in the current thread.