2016-03-26 4 views
2

Моего вопроса довольно трудно объяснить, я попытаюсь объяснить кратко:сделки слишком много государственных

Я пытаюсь воспроизвести таймер, как этот таймер на этом сайте: https://cstimer.net/

Проблемы I есть это: мне приходится иметь дело со многим «государством» и много событий:

типа события, у меня есть:

Chrono не запускается -> жмет «Space» -> цвет становится оранжевым - > после 500ms -> chrono становится зеленым -> Я освобождаю пространство -> chrono s tart -> Я нажимаю пробел -> остановка хроном

Я бы написал код, который делает это. Проблема в том, что мой код становится очень сложным из-за слишком большого количества «если».

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(); } 

... 
... 

Это ужасно, потому что я должен иметь переменную флагов, чтобы предотвратить остановку хронографа сразу после запуска.

Я ищу способ правильно управлять этим.

Я слышал о конечном состоянии машины, я не знаю, является ли это хорошим решением.

В настоящее время я использую response/redux и jquery для событий, но я могу добавить любые библиотеки, которые могут вам помочь.

Спасибо Вам

+0

Вы должны выбрать цвет в своих редукторах. Вы также не должны использовать React и jQuery вместе, особенно для обработки событий. Если это не имеет смысла, я обязательно прочитаю документы React и Redux, прежде чем продолжить. – pfkurtz

ответ

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" 
}) 
+0

Спасибо, это хороший, понятный подход к решению моей проблемы. Я постараюсь сделать с ним что-то хорошее :) – Epitouille

Смежные вопросы