【问题标题】:How to detect if a observable has not emitted any events for specific time in RxSwift如何在 RxSwift 中检测 observable 是否在特定时间内没有发出任何事件
【发布时间】:2017-06-27 23:44:45
【问题描述】:

我正在尝试检测 observable(我的情况 button.rx.tap)是否在 3 秒内没有发出任何值。如果是,我想更新用户界面。到目前为止,这是我的尝试:

Observable<Int>.interval(3, scheduler: MainScheduler.instance)
    .takeUntil(button.rx.tap) // I know take until will stop the timer sequence 
    .subscribe({ event in
        print(event)
        UIView.animate(withDuration: 0.4, animations: {
            if let number = event.element {
                let scale: CGFloat = number % 2 == 0 ? 1.5 : 1.0
                self.button.transform = CGAffineTransform(scaleX: scale, y: scale)
            }
        })
    })
    .addDisposableTo(disposeBag)

我的目标是在按钮未点击三秒钟时为视图设置动画。我尝试过 scandistinctUntilChangeddebounce,但我遇到的大多数组合运算符只会在可观察项发出项目时才会发出项目。非常感谢任何帮助。

【问题讨论】:

    标签: swift reactive-programming rx-swift rx-cocoa


    【解决方案1】:
    enum Event {
    case tap
    case timeout
    }
    
    let tapOrTimeout = button.rx.tap
      .map { _ in Event.tap }
      .timeout(3, scheduler: MainScheduler.instance)
      .catchErrorJustReturn(.timeout)
    
    Observable.repeatElement(tapOrTimeout).concat()
      .subscribe(onNext: { event in
        switch event {
        case .tap: tapHandler()
        case .timeout: callForAttention()
        }
      })
    
    • timeout(_:scheduler:) 如果在 3 秒内没有事件从链中出来,则会引发错误。
    • catchErrorJustReturn(_:) 会将错误转换为 .timeout 事件
    • 此时,如果 observable 超时,它也会完成,因此之后不会发生任何事情。使用Observable.repeatElement(_:).concat(),我们首先创建一个Observable&lt;Observable&lt;Event&gt;&gt;,然后连接内部可观察对象。在我们的例子中,这意味着我们将订阅第一个,如果第一个完成,我们将重新订阅同一个 observable。

    如果我们希望只播放一次callForAttention() 动画,我们可以执行以下操作

    let tap = button.rx.tap
      .map { _ in Event.tap }
    
    let tapOrTimeout = tap  
      .timeout(3, scheduler: MainScheduler.instance)
      .catchErrorJustReturn(.timeout)
    
    Observable.of(tapOrTimeout, tap).concat()
      .subscribe(onNext: { /* same as above */})
    

    这样,我们首先超时,然后只在点击发生时发出一个事件。

    【讨论】:

    • 不错!感谢您的回答
    猜你喜欢
    • 2020-02-11
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多