Search code examples
iosswiftrx-swiftfrpthrottling

change throttle parameter dynamically


Is it possible to change the throttle parameter (in this case "30") dynamically at runtime? Or do I have to create a new subscription with a new throttle time?

let disposable = Observable.combineLatest(objectA.asObservable().skip(1), 
                                          objectB.asObservable().skip(1))
                           .throttle(30, 
                                     scheduler: ConcurrentDispatchQueueScheduler(qos: .background))
                           .subscribe(onNext: { [unowned self] _ in
                    self.update()
            })

My solution would be to dispose of the current subscription and create a new subscription with the new desired throttle time. But is there a better solution?


Solution

  • The functional, declarative nature of RxSwift favors making a new observable/subscription with new parameters as needed instead of changing the throttle parameter dynamically for an existing observable.

    For example, make a function for your observable that sets the throttle interval.

    func throttled(with interval: Double) -> Observable<({TYPE_OF_A}, {TYPE_OF_B})>
    {
        let scheduler = ConcurrentDispatchQueueScheduler(qos: .default)
        return Observable
            .combineLatest(objectA.asObservable().skip(1),
                           objectB.asObservable().skip(1))
            .throttle(interval,
                      scheduler: scheduler)
    }
    

    Then, if you need to dispose the subscription, you can use a dispose bag and subscribe again with a new throttle parameter.

    var bag: DisposeBag! = DisposeBag()
    
    throttled(with: 30).subscribe(onNext: { _ in
        self.update()
    }).disposed(by: bag)
    
    bag = DisposeBag()
    
    throttled(with: 20).subscribe(onNext: { _ in
        self.update()
    }).disposed(by: bag)
    
    bag = DisposeBag()
    
    throttled(with: 10).subscribe(onNext: { _ in
        self.update()
    }).disposed(by: bag)