RxSwift - Schedulers

18 篇文章 0 订阅

Scheduler

简单来说Scheduler就是进程执行的上下文(也可以说程序执行的上下文)。上下文(context)可以是一个线程(thread),一个派发列队(dispatch queue),或者是用于OperationQueueScheduler中的NSOperation。这里有一个好例子说明调度者怎样被使用:

由上图可知,我们可能在后台调度者中(Background Scheduler)进行网络请求,然后缓存数据。并传递数据给所有的订阅者,大多数时候会回到MainScheduler,MainScheduler位于主线程的顶部。因为更新UI操作,必须在主线程。所以会切换到MainScheduler。注意:调度者(Scheduler)不是线程。

几种内嵌Scheduler(Builtin schedulers

CurrentThreadScheduler (Serial scheduler)

当前线程的调度者,这也是默认的调度者用于产生元素。

MainScheduler (Serial scheduler)

MainScheduler是主线程的一部分,这个调度者是经常用于处理用户界面的改变(即执行UI工作)和执行一些高优先级的任务。长时间任务不应该在该调度者中执行,比如:向服务器请求数据,其他繁重的任务。除此之外,如果你执行链式响应(side effects)来更新UI,你必须转换到MainScheduler,保证屏幕UI更新成功。MainScheduler也用于执行所有的计算,当使用Units、Driver。Driver确保了计算经常被执行在MainScheduler,让你有能力直接绑定数据到用户界面。下面是MainScheduler类的部分源码:
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()
}
由上面代码可知,MainScheduler是继承于SerialDispatchQueueScheduler,有instance单例,并且初始化时指定了运行线程为主线程(DispatchQueue.main),我们经常使用MainScheduler.instance来获取主线程并且配合observeOn操作符进行使用。

SerialDispatchQueueScheduler (Serial scheduler)

SerialDispatchQueueScheduler管理着串行派发列队(serial DispatchQueue)的抽象工作。它将确保即使是并发派发列队(concurrent dispatch queue )被传递,也将被转换为串行。在使用observeOn操作符的时候,这个调度者有几个非常大的优势。你能够使用该调度者处理后台任务,而且使用串行的方式更好的执行。例如:如果你有一个应用跟服务端进行交流(as in a Firebase or GraphQL application),你可能想避免派发多个,同时的请求,这会给服务端导致太大的压力。该调度者是完成满足你的工作就像一个串行任务列队一样,按顺序执行。

ConcurrentDispatchQueueScheduler (Concurrent scheduler)

ConcurrentDispatchQueueScheduler跟SerialDispatchQueueScheduler有些类似,也是管理DispatchQueue的抽象工作.主要的区别是这次不是串行列队而是一个并发列队。当使用observeOn的时候,该调度者并不算最佳选择。ConcurrentDispatchQueueScheduler是多任务、长耗时、需要同步执行任务的首选。

OperationQueueScheduler (Concurrent scheduler)

OperationQueueScheduler非常相似于ConcurrentDispatchQueueScheduler,但是并不是跟DispatchQueue一起工作,而是与NSOperationQueue一起工作。有时,你需要更多的对于并发的工作控制权限,但是你不能够在ConcurrentDispatchQueueScheduler进行操作,可以选择使用OperationQueueScheduler。
如果需要很好的设置最大数量的并发工作,OperationQueueScheduler是很好的选择。因为你能够使用maxConcurrentOperationCount来设置最大的操作数量

TestScheduler

非常特殊,它是用于测试的,所以注意了,不能够在正常的开发中使用,应该仅仅是用于测试,它是RxTest库的一部分。

注意:有趣的事情是如果传递并发列队(concurrent queue)到串行调度者(serial scheduler),RxSwift将确保并发列队变成串行列队(serial queue)。同理:如果传递串行列队到并发调度者,也会将串行列队变成并发列队(concurrent queue)


转换调度者(Switching schedulers)
在rx中一个最重要的事情之一就是可以有能力在任意时候转换调度者(Switching schedulers)。没有任何的限制,除了一个被强加的,由内部进程生成事件。
在线程这部分主要有两个操作符:observeOn 和 subscribeOn ,常用的还是 observeOn 。observeOn是ObservableType扩展中的一个方法:
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<Self.E>
}

调用 observeOn 指定接下来的操作在哪个线程,也可以理解为在哪个scheduler监听Observable.一个比较典型的例子:在后台发起网络请求,然后解析数据,最后在主线程刷新页面。我们可以先使用subscribeOn切换到后台发送请求并解析数据,在使用observeOn切换回到主线程更新页面。或者使用两次observeOn

  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")
        }
调用 subscribeOn 决定订阅者的操作执行在哪个线程。对于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<Self.E>
}

当然,如果我们没有明确调用这两个操作,后面的操作都是在当前线程执行的。对于调度者使用的简单事例可以看这里


参考:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django-Celery是一个用于在Django应用中集成Celery任务队列的插件。它允许你将耗时的任务异步执行,从而提高应用的性能和响应速度。下面是一些使用Django-Celery的步骤: 1. 安装Celery和Django-Celery:首先,确保你已经安装了Celery和Django-Celery。你可以通过运行以下命令来安装它们: ``` pip install celery django-celery ``` 2. 配置Celery:在Django项目的`settings.py`文件中,添加以下配置: ```python # settings.py # 配置Celery Broker(消息代理) BROKER_URL = 'amqp://guest:guest@localhost:5672//' # 配置Celery Backend(结果存储) CELERY_RESULT_BACKEND = 'db+sqlite:///results.sqlite' # 配置Celery Beat(定时任务) CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' ``` 请根据你的实际情况修改上述配置。 3. 创建Celery App:在你的Django项目中,创建一个名为`celery.py`的文件,并添加以下代码: ```python # celery.py from celery import Celery app = Celery('your_project_name') # 配置Celery app.config_from_object('django.conf:settings', namespace='CELERY') # 自动从Django app中加载任务 app.autodiscover_tasks() ``` 确保将`your_project_name`替换为你的项目名称。 4. 创建任务:在Django app中创建一个任务。例如,你可以在你的app目录下创建一个名为`tasks.py`的文件,并添加以下代码: ```python # tasks.py from celery import shared_task @shared_task def add(x, y): return x + y ``` 这是一个简单的任务示例,将两个数字相加并返回结果。 5. 启动Celery Worker:运行以下命令来启动Celery worker: ``` celery -A your_project_name worker --loglevel=info ``` 确保将`your_project_name`替换为你的项目名称。 6. 调用任务:在你的Django应用程序中,你可以通过导入任务函数并调用它来触发任务的执行。例如: ```python from your_app.tasks import add result = add.delay(1, 2) ``` 这里使用了`delay()`方法来异步调用任务。你也可以使用`apply_async()`方法来更精确地控制任务的执行。 这些是使用Django-Celery的基本步骤。你还可以配置更多高级选项,如任务重试、任务结果存储等。请参考Django-Celery的官方文档以获取更多详细信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值