0

我有一个SignalProducer producer异步发送Ints的。我可以将这些值与

producer.scan(0, +)

假设我想将总和重置为0如果它是> 10并且 1 秒内没有发送其他值。我的第一次尝试是这样的:

producer
  .scan(0, +)
  .flatMap(.latest) { n -> SignalProducer<Int, NoError> in
    if n <= 10 {
        return SignalProducer(value: n)
    } else {
        return SignalProducer.merge([
            SignalProducer(value: n),
            SignalProducer(value: 0).delay(1, on: QueueScheduler.main)
            ])
    }
  }

虽然这会正确发送0,但它不会重置 中的状态scan。即,一系列9, 8, long pause, 7发送9, 17, 0, 24

有没有办法以正确重置状态的方式结合这两个概念?

4

1 回答 1

2

我将使用startWithSignal获取对生成Signal的访问权限,以创建重置触发器以与传入值合并。我使用枚举作为我的值来指示进入的值scan是重置触发器还是Int要累积。

enum ValOrReset {
    case val(Int)
    case reset
}


producer.startWithSignal { signal, _ in
    resetTrigger = signal
        .debounce(TimeInterval(1.0), on: QueueScheduler.main)
        .map { _ in .reset }

    signal
        .map { val in .val(val) }
        .merge(with: resetTrigger)
        .scan(0) { (state, next) in
            switch next {
            case .val(let val):
                return state + val
            case .reset:
                if state > 10 {
                    return 0
                }
                else {
                    return state
                }
            }
        }
        .observeValues { val in
            print(val)
        }
}

有效的方法startWithSignal是确保在闭包完成之前不会出现任何值,这意味着您可以创建多个下游信号并将它们连接在一起而不必担心丢失任何值,即使生产者同步发送值也是如此。

于 2018-04-24T14:30:00.277 回答