【问题标题】:RxSwift - Debounce/Throttle "inverse"RxSwift - 去抖动/油门“逆”
【发布时间】:2016-05-28 01:39:35
【问题描述】:

假设我有一个即时消息应用程序,每次收到消息时都会发出哔声。我想debounce 发出哔哔声,但我想在第一条消息到达时播放哔哔声,而不是为后续消息播放哔声(例如,2 秒的时间跨度)。

另一个例子可能是:我的应用程序发送输入通知(因此我正在与之聊天的用户可以看到我正在输入消息)。我想在开始输入时发送输入通知,但仅以 X 秒为间隔发送新的通知,因此我不会为我输入的每个字符发送输入通知。

这有意义吗?有运营商吗?现有的运营商能做到吗?

这是我的第一个示例的代码。我现在用debounce 解决它,但这并不理想。如果我每隔 1 秒收到 1000 条消息,则在最后一条消息到达之前它不会播放声音(我想在第一条消息上播放声音)。

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

谢谢!

【问题讨论】:

标签: ios swift rx-swift


【解决方案1】:

针对 RxSwift 3 进行了更新并改进了 throttle 运算符

在 RxSwift 3.0.0-beta.1 中引入 throtlle 运算符的新行为,您可以像这样使用它:

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

旧版答案

使用window 运算符,然后使用flatMapObservable<Observable<Type>> 转换为平面Observable

此示例代码仅在每 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)

【讨论】:

  • 我目前正在使用类似的解决方案,但我觉得还有改进的空间。我想避免双重订阅。感谢您的回答!
  • 肯定有改进的余地。现在它可以在没有双重订阅的情况下使用。
【解决方案2】:

Window 是一个很好的解决方案,但我发现示例运算符更直观且行为正确。

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

油门操作没有按照我的想法进行。

对于那些也觉得油门太混乱的人:

“只有当源 observable 在指定时间段内停止发送事件时,节流才会转发事件。这不适用于常规事件传递”for more details

在这种情况下,您想要的过滤器是

sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance))

【讨论】:

  • "只有当源 observable 在指定时间段内停止发送事件时,节流才会转发事件。这不适用于常规事件传递" 也许过去就是这样,但知道这里描述的是 DEBOUNCE 而不是 THROTTLE
猜你喜欢
  • 2017-08-26
  • 2017-09-10
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多