RxSwift - Debounce/Throttle "inverse"

Допустим, у меня есть приложение для обмена мгновенными сообщениями, которое воспроизводит звуковой сигнал каждый раз, когда приходит сообщение. я бы хотел debounce звуковые сигналы, но я хотел бы воспроизвести звуковой сигнал для первого поступившего сообщения, а не для следующих (например, в течение 2 секунд).

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

Имеет ли это смысл? Есть ли оператор для этого? Может ли это быть достигнуто с существующими операторами?

Это мой код для первого примера. Я решаю это сейчас с debounce, но это не идеально. Если я получу 1000 сообщений с интервалом в 1 секунду, он не будет воспроизводить звук до тех пор, пока не прибудет последнее сообщение (я хотел бы воспроизвести звук на первом).

self.messagesHandler.messages
            .asObservable()
            .skip(1)
            .debounce(2, scheduler: MainScheduler.instance)
            .subscribeNext { [weak self] message in
                    self?.playMessageArrivedSound()
            }.addDisposableTo(self.disposeBag)

Спасибо!

2 ответа

Решение

Обновлен для RxSwift 3 и улучшен throttle оператор

С новым поведением throtlle оператор, представленный в RxSwift 3.0.0-beta.1, вы можете использовать его просто так:

    downloadButton.rx.tap
    .throttle(3, latest: false, scheduler: MainScheduler.instance)
    .subscribe(onNext: { _ in
        NSLog("tap")
    }).addDisposableTo(bag)

Старая версия ответа

использование window оператор, а затем преобразовать Observable<Observable<Type>> к квартире Observable с помощью flatMap,

Этот пример кода печатает "касание" только для первого касания в окнах каждые 3 секунды (или если число касаний превышает 10000).

    downloadButton.rx_tap
    .window(timeSpan: 3, count: 10000, scheduler: MainScheduler.instance)
    .flatMap({ observable -> Observable<Void> in
        return observable.take(1)
    })
    .subscribeNext { _ in
        NSLog("tap")
    }.addDisposableTo(bag)

Окно - отличное решение, но я считаю, что пример оператора более интуитивен, а также с правильным поведением.

messagesHandler.messages
               .sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance))
               .subscribeNext { [weak self] message in
                    self?.playMessageArrivedSound()
               }.addDisposableTo(self.disposeBag)

Дроссельная заслонка не делает то, что я думал, что должен.

Для людей, которые также находят газ, слишком запутанно:

"throttle будет пересылать событие только после того, как наблюдаемый источник перестанет отправлять события в течение указанного периода времени. Это не очень хорошо работает с обычной доставкой событий" для более подробной информации.

В этом случае фильтр, который вы хотите

sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance))
Другие вопросы по тегам