RXSwift действует во время разоблачения

Я хотел бы иметь Observable, который во время дебаунса (во временном интервале, когда мы все еще не испускаем значение) произойдет что-то еще, например, покажет счетчик.

Поэтому в моем примере кода я ссылаюсь только на свое представление ПОСЛЕ того, как значение выдается.

observable.debounce(0.3, scheduler: MainScheduler.instance).do(onNext: { spinner in 
    spinner.stop() //here I set it to stop, I want to run spinner.start() while we are in the debounce area
}).subscribe().disposedBy(disposeBag)

Я думал, что этот вопрос может соответствовать моим потребностям, но не уверен, что это именно то, о чем я прошу: RxSwift - Debounce/ Дроссель инверсный


person Eyzuky    schedule 10.10.2018    source источник


Ответы (2)


Насколько я понимаю вопрос, цель состоит в том, чтобы инициировать какое-то действие на период отката/дросселирования.

Это относительно просто сделать для дросселирования (т.е. запускать не более одного раза за период времени): в основном используйте оператор .window(), навешивайте на него желаемое действие, а затем используйте результат .window() для фактического дросселирования.

С debounce (т. е. однократным генерированием после того, как восходящий поток не генерировался в течение заданного периода времени) это кажется сложным, но, вероятно, также выполнимым.

person Maxim Volgin    schedule 10.10.2018
comment
Ну, это может происходить много раз.. это запрос сервера, и если он выполняется, я хочу, чтобы представление было скрыто - person Eyzuky; 10.10.2018
comment
Итак, вы в основном хотите скрыть представление, пока выполняется каждый запрос, и показывать его снова после получения ответа? Как во все это вписывается дебаунс, вы запускаете запросы параллельно? - person Maxim Volgin; 10.10.2018
comment
хм, это общий вопрос, представление скрыто - это всего лишь пример. Например, запрос сервера может отображать счетчик при отклонении. - person Eyzuky; 10.10.2018
comment
Вариант использования все еще неясен, особенно часть устранения дребезга. Просто дикое предположение, применимо ли в вашем случае rxmarbles.com/#sample? - person Maxim Volgin; 10.10.2018
comment
Вариант использования просто не имеет значения. Я хочу знать, смогу ли я это сделать или нет .. Но я обязательно посмотрю вашу ссылку и обновлю :) спасибо - person Eyzuky; 10.10.2018
comment
Ах, вы обновили вопрос - теперь я думаю, что понимаю, что вы имеете в виду. Я обновил свой ответ для дроссельной заслонки, нужно будет больше подумать о подавлении дребезга. - person Maxim Volgin; 10.10.2018
comment
Windows кажется правильной вещью! будет ли это гарантировать, что будет запущено последнее испускаемое значение? потому что именно поэтому я использовал debounce - person Eyzuky; 10.10.2018
comment
Я не понимаю, как его использовать, хотя - person Eyzuky; 10.10.2018
comment
.last()/.takeLast() для каждой последовательности, которую производит .window() (при условии, что вам нужна последняя, ​​а не первая), а затем .concatMap() их вместе. - person Maxim Volgin; 10.10.2018

На самом деле не имеет значения, делаете ли вы сетевой запрос или используете debounce, потому что сетевой запрос будет выполнен с использованием flatMap и является независимым наблюдаемым. Вот пример кода, который будет анимировать индикатор активности во время выполнения сетевого запроса:

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let _activityIndicator = activityIndicator! // to avoid dealing with self.
        button.rx.tap
            .flatMapLatest { () -> Observable<Int> in
                let request = Observable<Int>.timer(5.0, scheduler: MainScheduler.instance)
                return Observable.using({ ActivityIndicatorAnimator(_activityIndicator) }, observableFactory: { _ in request })
            }
            .subscribe()
            .disposed(by: bag)
    }

    let bag = DisposeBag()
}

class ActivityIndicatorAnimator: Disposable {
    init(_ spinner: UIActivityIndicatorView) {
        self.spinner = spinner
        spinner.startAnimating()
    }

    func dispose() {
        spinner.stopAnimating()
    }

    let spinner: UIActivityIndicatorView
}

В приведенном выше примере используется таймер для имитации сетевого запроса. Оператор using создаст ресурс при запуске наблюдаемого и удалит ресурс, когда наблюдаемое завершится. Ресурс ActivityIndicatorAnimator запускает анимацию при создании ресурса и останавливает ее при удалении ресурса.

В репозитории RxSwift есть более сложный пример под названием ActivityIndicator, который ведет подсчет того, сколько раз он был запущен и остановлен, и может использоваться для мониторинга нескольких сетевых запросов.

person Daniel T.    schedule 11.10.2018
comment
Это прекрасно. Я многому у него учусь. Я не думаю, что это дает прямой ответ на вопрос, но дает представление о том, как использовать разные подходы для решения одной и той же проблемы. Отметить как избранное - person Eyzuky; 11.10.2018