如何观察 bool 值流并延迟值变化?
How it is possible to observe stream of bool values with delay on value change?
我有这样的速度观察器(这是描述问题的简单版本):
class SpeedManager {
var speed = Variable(0.0)
private var limit = 0.2
func speedObserver() -> Observable<Bool> {
return speed.asObservable().map{[=10=] >= self.limit}
}
}
我所做的只是在达到限制时验证速度。
所以我收到了这种流:
false----->true----->false----->true----->true----->true----->true
比我这样做:
let speedManager = SpeedManager()
let observable = speedManager.speedObserver().distinctUntilChanged()
其中 observable
将重新播放这种流:
假----->真----->假----->真----->假----->真----->假
所以我只需要添加步骤来验证 observable
事件是否为 true
并且在 10 秒内为真。
基本上如果 observable
下一个事件是 true
我应该等待 10 秒来验证下一个事件是否不会是 false
。
你的问题不是很清楚。让我解释。您写道:
So I just need to add step that will validate if observable event is
true and it is true during 10 seconds.
描述了两种情况:
- 只有第一个
true
事件被视为触发 10 秒计时器。每个下一个 true
事件都会被忽略并且不会产生计时器,直到 false
事件取消计时器。
- 每个
true
事件都应该产生 observable
等待任何 false
事件 10 秒,如果 false
没有发生 - 你可以观察到的火灾。
第一种情况很简单:
let observable1 = observable
.debounce(10, scheduler: MainScheduler.instance)
.filter({ [=10=] == true })
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
第二种情况更难:
let observableEnumerated = observable
.scan((false, 0)) { (value, next) -> (Bool, Int) in
return (next, value.1 + 1)
}
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
let observableEnumeratedFalse = observableEnumerated
.filter({ [=11=].0 == false })
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
let observable1 = observableEnumerated
.filter({ [=11=].0 == true })
.delay(10, scheduler: MainScheduler.instance)
.withLatestFrom(observableEnumeratedFalse){(trueIndex: [=11=].1, falseIndex: .1)}
.filter({ [=11=].trueIndex > [=11=].falseIndex })
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
observableEnumerated
- 只是枚举你的 Bool
observable
observableEnumeratedFalse
- 只接受 false
枚举事件
那么你只需要 true
个事件。将它们每个延迟 10 秒。在延迟之后,您从 false
枚举可观察对象中获取最后一个值。如果最后一个 false
事件的索引低于当前延迟的 true
事件 - 这就是您所需要的。
第二种情况没有测试,只是展示了一种处理任务的方法。大多数时候使用 debounce
的第一个解决方案将是您的选择。顺便说一句,throttle
不太适合这种情况,请阅读他们的描述以充分了解他们的可能性。
我有这样的速度观察器(这是描述问题的简单版本):
class SpeedManager {
var speed = Variable(0.0)
private var limit = 0.2
func speedObserver() -> Observable<Bool> {
return speed.asObservable().map{[=10=] >= self.limit}
}
}
我所做的只是在达到限制时验证速度。
所以我收到了这种流:
false----->true----->false----->true----->true----->true----->true
比我这样做:
let speedManager = SpeedManager()
let observable = speedManager.speedObserver().distinctUntilChanged()
其中 observable
将重新播放这种流:
假----->真----->假----->真----->假----->真----->假
所以我只需要添加步骤来验证 observable
事件是否为 true
并且在 10 秒内为真。
基本上如果 observable
下一个事件是 true
我应该等待 10 秒来验证下一个事件是否不会是 false
。
你的问题不是很清楚。让我解释。您写道:
So I just need to add step that will validate if observable event is true and it is true during 10 seconds.
描述了两种情况:
- 只有第一个
true
事件被视为触发 10 秒计时器。每个下一个true
事件都会被忽略并且不会产生计时器,直到false
事件取消计时器。 - 每个
true
事件都应该产生observable
等待任何false
事件 10 秒,如果false
没有发生 - 你可以观察到的火灾。
第一种情况很简单:
let observable1 = observable
.debounce(10, scheduler: MainScheduler.instance)
.filter({ [=10=] == true })
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
第二种情况更难:
let observableEnumerated = observable
.scan((false, 0)) { (value, next) -> (Bool, Int) in
return (next, value.1 + 1)
}
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
let observableEnumeratedFalse = observableEnumerated
.filter({ [=11=].0 == false })
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
let observable1 = observableEnumerated
.filter({ [=11=].0 == true })
.delay(10, scheduler: MainScheduler.instance)
.withLatestFrom(observableEnumeratedFalse){(trueIndex: [=11=].1, falseIndex: .1)}
.filter({ [=11=].trueIndex > [=11=].falseIndex })
.share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
observableEnumerated
- 只是枚举你的 Bool
observable
observableEnumeratedFalse
- 只接受 false
枚举事件
那么你只需要 true
个事件。将它们每个延迟 10 秒。在延迟之后,您从 false
枚举可观察对象中获取最后一个值。如果最后一个 false
事件的索引低于当前延迟的 true
事件 - 这就是您所需要的。
第二种情况没有测试,只是展示了一种处理任务的方法。大多数时候使用 debounce
的第一个解决方案将是您的选择。顺便说一句,throttle
不太适合这种情况,请阅读他们的描述以充分了解他们的可能性。