处理太多状态

deal with too many state

我的问题很难解释,我会尽量简单地解释一下:

我试着在这个网站上重现一个像这个计时器的计时器:https://cstimer.net/

我遇到的问题是:我必须处理许多 "states" 和许多事件:

我的活动类型是:

计时未启动 -> 我按下 "Space" -> 颜色变为橙色 -> 500 毫秒后 -> 计时变为绿色 -> 我释放 space -> 计时开始 -> 我按下space -> 计时停止

我会编写执行此操作的代码。问题是我的代码因为太多"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 来处理事件,但我可以添加任何有帮助的库。

谢谢你

看看RxJS。 RxJS 是一个响应式库,允许您操作异步流。在您的特定示例中,它可能有助于保持您的代码声明性并防止它被全局状态弄乱。

有关介绍,请在此处查看 egghead.io 课程:https://egghead.io/lessons/rxjs-what-is-rxjs

或查看响应式编程简介:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

例如在你的情况下,看看这个 fiddle 你可以从中做出更复杂的例子: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"
})