处理太多的国家

时间:2016-03-26 16:37:48

标签: debugging redux state-machine

我的问题很难解释,我会试着简单解释一下:

我尝试在此网站中重现像此计时器这样的计时器: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用于事件,但我可以添加任何可以提供帮助的库。

谢谢你

1 个答案:

答案 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"
})