我的问题很难解释,我会试着简单解释一下:
我尝试在此网站中重现像此计时器这样的计时器:https://cstimer.net/
我遇到的问题是:我必须处理许多“状态”和许多事件:
我所遇到的事件类型是:
Chrono未启动 - >我按“空格” - >颜色变成橙色 - > 500ms后 - >计时变为绿色 - >我发布空间 - >计时开始 - >我按空格 - >计时停止
我会编写那样做的代码。问题是由于“if”太多,我的代码变得非常复杂。
if (!chronoIsStarted and SpaceIsPressed) { chrono.color = orange }
if (lastKeyDown - lastKeyUp >= 500 and !chronoIsStarted) { chrono.color = green }
if (keyup == space and lastKeyDown - lastKeyUp >= 500) { chono.start(); }
...
...
这很糟糕,因为我必须有标志变量来防止chrono在启动后直接停止。
我正在寻找一种妥善管理的方法。
我听说有限的机器状态,我不知道它是否是一个很好的解决方案。
目前,我将react / redux和jquery用于事件,但我可以添加任何可以提供帮助的库。
谢谢你
答案 0 :(得分:1)
看看RxJS。 RxJS是一个反应库,允许您操作异步流。在您的特定示例中,它可以帮助您保持代码声明性并防止它与全局状态混乱。
有关介绍,请查看egghead.io课程:https://egghead.io/lessons/rxjs-what-is-rxjs
或查看反应式编程的介绍:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
例如,在您的情况下,请看一下这个小提琴,您可以从中制作更复杂的示例:http://jsfiddle.net/bryanph/5rkbxgtj/
// press space for clickSpace event
// hold space for holdSpace event
var chrono = {
isStarted: false
}
document.body.style.backgroundColor = "red"
var spaceUp = Rx.Observable.fromEvent(document.body, 'keyup')
.filter(x => x.keyCode === 32)
var spaceDown = Rx.Observable.fromEvent(document.body, 'keydown')
.filter(e => e.keyCode === 32)
.filter(e => !e.repeat)
.partition(x => chrono.isStarted)
var chronoStarted = spaceDown[0];
var chronoStopped = spaceDown[1];
var clickSpace = chronoStopped.flatMap(function(e) {
return spaceUp.timeout(200, Rx.Observable.empty())
})
var holdSpace = chronoStopped
.flatMap(function(e) {
return Rx.Observable
.return(e)
.delay(500)
.takeUntil(spaceUp)
.take(1)
})
clickSpace.subscribe(function(x) {
document.body.style.backgroundColor = "orange"
})
holdSpace.subscribe(function(x) {
console.log('called')
document.body.style.backgroundColor = "green"
})