lamehacks

Stuff is fun

Implementing a state machine in javascript

For reasons beyond my understanding, and despite their relative ubuiquity, state machines are still largely disregarded by a huge slice of programmers.
Many problems can be modeled using a state machine, the most common one is the maintenance of a database table column which holds some kind of state. Many programmers don’t realize that they are in presence of a state machine and end up throwing bits of code accross the codebase to flip state whenever necessary. They are basically resourcing to a messy ad-hoc implementation of a state machine without realizing it. Personally I’ve been tearing my hair off because of this countless times.
Simply put, if you’re going to use ad-hoc code to flip states among three or more possible values, you are going to make mistakes and ultimately render you codebase unmanageable.

But what’s a sate machine anyway?

From wikipedia:
A finite-state machine (FSM) or finite-state automaton (plural: automata), or simply a state machine, is a mathematical model used to design computer programs and digital logic circuits. It is conceived as an abstract machine that can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state. It can change from one state to another when initiated by a triggering event or condition, this is called a transition. A particular FSM is defined by a list of the possible states it can transition to from each state, and the triggering condition for each transition.

To show how harmless state machines are, I’m going to model myself with a state machine. More specifically I’ll use a state machine to model a day at work.

So, my average work day consists of writting software in front of a computer screen. When I get bored I make a pause for coffee, after a few minutes I go back to work. If somebody calls for a meeting I imediatly follow, regardless if I’m working or having a coffee. Once the meeting is over I go back to work.

Let’s put this into a diagram for clarity.

If you’re an electrical enginner like myself, you’ll notice the similarity between this diagram and a state diagram of a circuit with flip-flops. That is not a coincidence, sequential logic circuits are state machines.

On to the implementation, I’ll use javascript, but obviously this can be done in your favorite language. But first, let’s start by specifying the sate machine by writting down all the states and transitions among them.

states = [
	{
		'name':'working',
		'initial':true,
		'events':{
			'bored':'coffee',
			'call_for_meeting':'meeting',
		}
	},
	{
		'name':'coffee',
		'events':{
			'break_over':'working',
			'call_for_meeting':'meeting'
		}
	},
	{
		'name':'meeting',
		'events':{
			'meetings_over':'working'
		}
	},
];

This is pretty self-explanatory.
The implementation is straightforward too: a constructor sets up the state machine when provided with a state machine definition such as the example above. Aditionally we define two extra methods, one to handle events and other to report the current state. What could be simpler?

function StateMachine(states){
	this.states = states;
	this.indexes = {}; //just for convinience
	for( var i = 0; i< this.states.length; i++){
		this.indexes[this.states[i].name] = i;
		if (this.states[i].initial){
			this.currentState = this.states[i];
		}
	}
	this.consumeEvent = function(e){
		if(this.currentState.events[e]){
			this.currentState = this.states[this.indexes[this.currentState.events[e]]] ;
		}
	}
	this.getStatus = function(){
		return this.currentState.name;
	}
}

And that’s it! Let’s see it in action.

sm = new StateMachine(states);
sm.getStatus(); // will return 'working'
 
sm.consumeEvent('bored');
sm.getStatus(); // I went for coffee
 
sm.consumeEvent('call_for_meeting');
sm.getStatus(); //will return 'meeting'
 
sm.consumeEvent('bored'); //doesn't matter how boring a meeting can be...
sm.getStatus(); //will still return 'meeting'
 
sm.consumeEvent('meetings_over')
sm.getStatus(); // 'working'

In many scenarios you might want to add some extra features such as signaling, external persistence or hooks, but this is basically it.

Related Posts:

Tags: , ,

13 Responses to “Implementing a state machine in javascript”

  1. Insight Says:

    Obviously going through the OPs article I accept it as its real so its pleasant reading from a writer that is writing it publically to consider.

  2. Merrill Jenks Says:

    Throughout this grand pattern of things you actually secure an A for hard work. For the moment I will yield to your position.

  3. Mig Says:

    Thanks for this great explanation and example! DOUBLE THUMBS UP

  4. cars Says:

    Car shopping is stressful. Now that there are hundreds of makes and models to choose from,
    not to mention promotions and payment options, it’s easy to become frustrated and stressed out. The information here will help make buying a car as easy and stress-free as possible.

  5. Roman Blöth Says:

    Dear Pedro,

    even more than a year after your post it’s still of use. Thanks a lot for your short and snappy introduction to state machines!

  6. Gupta Says:

    Hi Pedro,
    I liked this post.. I used this technique two years back for a project.. I saw comment from “Roman” that drives me to your site.. For my case, i ended up by adding “attributes” field to pass more information along with name and events fields(in XML not JSON).. Still, i had to consider few conditions(config settings) while transitioning to new state from a particular state. It’s kind a little messy, but worked out..

  7. ALavoie Says:

    Yet simple, still really helpful for our own sm implementation, thanks.

  8. Haydn' Says:

    Hey,
    thanks for this little implementation pattern.

    I only had to ad some action like


    },
    {
    ‘actions’:{ ‘EvtName1′: fName1,
    ‘EvtName2: fName2
    }
    }
    }
    ];

    and than call before state-change:
    ..
    this.currentState.actions[e]();
    ..

    Done! Perfect

  9. 상태머신 | Qoom Networks DevOps Blog Says:

    […] Implementing a state machine in javascript […]

  10. basos Says:

    Very nice idea. Actually I implemented a js micro library based on this. The states definitions is slightly modified but still transitions definitions are state based. I also added conditional transitions and actions.
    You can check the js-fsm library here
    https://github.com/basos9/js-fsm

  11. A Javascript Finite State Machine (FSM) | moregreyhair Says:

    […] The implementation is inspired by a post on lamehacks. […]

  12. Salina Says:

    It’s hard to find your posts in google. I found it on 22 spot, you should build quality backlinks , it will help you to get more
    visitors. I know how to help you, just type in google – k2 seo tips
    and tricks

  13. Mercedes Says:

    I read a lot of interesting posts here. Probably you
    spend a lot of time writing, i know how to save you a lot of
    work, there is an online tool that creates unique, SEO friendly articles in seconds, just search in google – laranitas free content source

Leave a Reply

. .

Entries (RSS) and Comments (RSS).