Simply put, it has three characteristics:
* The total number of states (state) is limited.
* At any moment, you are in only one state.
* Under certain conditions, there will be a transition from one state to another.
What it means to JavaScript is that many objects can be written as finite state machines.
For example, there is a menu element on the web page. When the mouse is hovering, the menu is displayed; when the mouse is moved away, the menu is hidden. If a finite state machine is used to describe it, this menu has only two states (show and hide), and the mouse will cause a state transition.
The code can be written as follows:
var menu = {
// Current state
currentState: 'hide',
// Bind event
initialize: function() {
var self = this;
self.on("hover", self.transition);
},
// State transition
transition: function(event){
switch(this.currentState) {
case "hide":
This.currentState = 'show';
doSomething();
case "show":
doSome thing();
break;
default:
console.log('Invalid State!');
break;
}
}
}; 🎜 >
As you can see, the writing method of finite state machine has clear logic and strong expressiveness, which is conducive to encapsulating events. The more states an object has and the more events that occur, the more suitable it is to use finite state machine writing.
In addition, the JavaScript language is a language with a lot of asynchronous operations. A common solution is to specify a callback function, but this will cause problems such as confusing code structure and difficulty in testing and debugging. Finite state machines provide a better way: link the asynchronous operation to the state change of the object. When the asynchronous operation ends, the corresponding state change occurs, which triggers other operations. This is more logically reasonable and easier to reduce the complexity of the code than solutions such as callback functions, event listening, and publish/subscribe.
The following introduces a finite state machine function library Javascript Finite State Machine. This library is very easy to understand and can help us deepen our understanding, and its functions are not weak at all.
This library provides a global object StateMachine. Using the create method of this object, you can generate an instance of a finite state machine.
Copy code
When generating, you need to provide a parameter object to describe the nature of the instance. For example, a traffic light (traffic light) can be described like this:
Copy code
events: [
{ name: 'warn', from: 'green', to: 'yellow' },
{ name: 'stop', from: 'yellow', to: 'red' },
{ name: 'ready', from: 'red', to: 'yellow' },
{ name: 'go', from: 'yellow ', to: 'green' }
]
});
The initial state of the traffic light is green, and the events attribute is the various events that trigger the state change. For example, the warn event changes the green state to the yellow state, the stop event changes the yellow state to the red state, and so on.
After generating an instance, you can query the current status at any time.
Copy code
The code is as follows: * fsm.current: Return the current state. * fsm.is(s): Returns a Boolean value indicating whether state s is the current state. * fsm.can(e): Returns a Boolean value indicating whether event e can be triggered in the current state.
* fsm.cannot(e): Returns a Boolean value indicating whether event e cannot be triggered in the current state.
Javascript Finite State Machine allows you to specify two callback functions for each event, taking the warn event as an example:
* onbeforewarn: Triggered before the warn event occurs.
* onafterwarn (can be abbreviated as onwarn): Triggered after the warn event occurs.
At the same time, it also allows specifying two callback functions for each state, taking the green state as an example:
* onleavegreen: Triggered when leaving the green state.
* onentergreen (can be abbreviated as ongreen): Triggered when entering the green state.
Assuming that the warn event changes the state from green to yellow, the order of occurrence of the above four types of callback functions is as follows: onbeforewarn → onleavegreen → onenteryellow → onafterwarn.
In addition to specifying separate callback functions for each event and status, you can also specify a common callback function for all events and statuses.
* onbeforeevent: Triggered before any event occurs.
* onleavestate: Triggered when leaving any state.
* onenterstate: Triggered when entering any state.
* onafterevent: Triggered after any event ends.
If there is an asynchronous operation in the event callback function (such as Ajax communication with the server), then we may want to wait until the asynchronous operation ends before the state changes. This requires the use of the transition method.
fsm.onwarn = function(){
light .fadeOut('slow', function() {
fsm.transition();
});
return StateMachine.ASYNC;
};
In the callback function of the above code, there is an asynchronous operation (light.fadeOut). If you do not want the state to change immediately, you must let the callback function return a StateMachine.ASYNC object, indicating that the state will not change temporarily; wait until the asynchronous operation is completed, and then call the transition method to cause the state to change.
Javascript Finite State Machine also allows you to specify an error handling function, which is automatically triggered when an event that is impossible to occur in the current state occurs.
var fsm = StateMachine.create({
/ / ...
error: function(eventName, from, to, args, errorCode, errorMessage) {
return 'event ' eventName ': ' errorMessage;
},
// ...
});
For example, if the current status is green, theoretically only a warn event may occur at this time. If a stop event occurs at this time, the above error handling function will be triggered.