Thursday, September 29, 2011

Javascript State Machine v2

Совершенно случайно набрел на библиотеку под названием State Machine.

Это библиотека, реализующая событийную модель основанную на состояниях.

При реализации сложной логики событий эта библиотека сильно упрощает жизнь разработчика.

Для чего она и что умеет. Я думаю начну с примера, который хорошо показывает ее возможности.

var fsm = StateMachine.create({

    events: [
      { name: 'start', from: 'none',   to: 'green'  },
      { name: 'warn',  from: 'green',  to: 'yellow' },
      { name: 'panic', from: 'green',  to: 'red'    },
      { name: 'panic', from: 'yellow', to: 'red'    },
      { name: 'calm',  from: 'red',    to: 'yellow' },
      { name: 'clear', from: 'red',    to: 'green'  },
      { name: 'clear', from: 'yellow', to: 'green'  },
    ],

    callbacks: {
      onbeforestart: function(event, from, to) { log("STARTING UP"); },
      onstart:       function(event, from, to) { log("READY");       },

      onbeforewarn:  function(event, from, to) { log("START   EVENT: warn!",  true);  },
      onbeforepanic: function(event, from, to) { log("START   EVENT: panic!", true);  },
      onbeforecalm:  function(event, from, to) { log("START   EVENT: calm!",  true);  },
      onbeforeclear: function(event, from, to) { log("START   EVENT: clear!", true);  },

      onwarn:        function(event, from, to) { log("FINISH  EVENT: warn!");         },
      onpanic:       function(event, from, to) { log("FINISH  EVENT: panic!");        },
      oncalm:        function(event, from, to) { log("FINISH  EVENT: calm!");         },
      onclear:       function(event, from, to) { log("FINISH  EVENT: clear!");        },

      onleavegreen:  function(event, from, to) { log("LEAVE   STATE: green");  },
      onleaveyellow: function(event, from, to) { log("LEAVE   STATE: yellow"); },
      onleavered:    function(event, from, to) { log("LEAVE   STATE: red");    async(to); return false; },

      ongreen:       function(event, from, to) { log("ENTER   STATE: green");  },
      onyellow:      function(event, from, to) { log("ENTER   STATE: yellow"); },
      onred:         function(event, from, to) { log("ENTER   STATE: red");    },

      onchangestate: function(event, from, to) { log("CHANGED STATE: " + from + " to " + to); }
    }
});

var async = function(to) {
    pending(to, 3);
    setTimeout(function() {
      pending(to, 2);
      setTimeout(function() {
        pending(to, 1);
        setTimeout(function() {
          fsm.transition(); // trigger deferred state transition
        }, 1000);
      }, 1000);
    }, 1000);
};

var pending = function(to, n) { log("PENDING STATE: " + to + " in ..." + n); };

fsm.start();

У нас есть состояние какого-то процесса, например ядерного синтеза, и датчики, сигнализирующие о текущем состоянии системы. Зеленый – все ОК. Желтый – предупреждение. Красный – тревога.

При переходе из одного состояния в другое система должна реагировать определенным образом на это. Например смена состояния с зеленого на желтый сопровождается генерацией событий onleavegreen, onyellow, onbeforewarn, onwarn, onchangestate, где мы соответствующим образом можем отреагировать на смену состояний процесса.

Также, в качестве примера возможностей библиотеки, функция async симулирует этапный переход из одного состояния процесса в другой. Метод transition является аналогом метода resolve у объекта $.Deferred() из jQuery. Он сообщяет StateMachine о готовности перехода из одного состояния в другое.

Как это все выглядит в динамике можно посмотреть тут.

No comments:

Post a Comment