Autrement dit, il a trois caractéristiques:
La copie de code est la suivante:
* Le nombre total d'États (État) est limité.
* À tout moment, vous n'êtes dans un seul état.
* Dans certaines conditions, il passera d'un état à l'autre.
Ce que cela signifie pour JavaScript, c'est que de nombreux objets peuvent être écrits comme des machines d'état finies.
Par exemple, il existe un élément de menu sur la page Web. Lorsque la souris oscille, le menu s'affiche; Lorsque la souris est éloignée, le menu est caché. Si vous utilisez la description de la machine à états finis, ce menu n'a que deux états (afficher et masquer) et la souris déclenchera une transition d'état.
Le code peut être écrit comme suit:
La copie de code est la suivante:
var menu = {
// Statut actuel
CurrentState: «Hide»,
// Événements de liaison
initialiser: function () {
var self = this;
self.on ("Hover", self.transition);
},
// Transition de statut
transition: fonction (événement) {
commutateur (this.currentState) {
cas "Hide":
this.currentState = 'show';
Dosomething ();
casser;
cas "show":
this.currentState = 'Hide';
Dosomething ();
casser;
défaut:
console.log («État non valide!»);
casser;
}
}
};
On peut voir que la méthode d'écriture des machines à états finies est claire dans la logique et l'expression forte, qui est propice à l'encapsulation des événements. Plus un objet a d'états et plus il se produit d'événements, plus il est approprié d'utiliser la méthode d'écriture de la machine à l'état fini.
De plus, JavaScript est une langue avec beaucoup d'opérations asynchrones. La solution couramment utilisée consiste à spécifier les fonctions de rappel, mais cela entraînera des problèmes tels que la structure de code confuse, difficile à tester et à déboguer. La machine d'état finie offre un meilleur moyen: accrocher les opérations asynchrones avec le changement d'état de l'objet. Lorsque l'opération asynchrone est terminée, un changement d'état correspondant se produit, déclenchant ainsi d'autres opérations. Ceci est plus logiquement raisonnable que la solution des fonctions de rappel, l'écoute des événements, la publication / d'abonnement, etc., et est plus facile de réduire la complexité du code.
Ce qui suit est une bibliothèque de machines d'état finie, JavaScript Finite State Machine. Cette bibliothèque est très facile à comprendre et peut nous aider à approfondir notre compréhension, et ses fonctions ne sont pas du tout faibles.
Cette bibliothèque fournit un objet global StateMachine, qui utilise la méthode de création de l'objet pour générer des instances d'une machine à états finie.
La copie de code est la suivante:
var fsm = stateMachine.Create ();
Lors de la génération, un objet de paramètre doit être fourni pour décrire les propriétés de l'instance. Par exemple, les feux de circulation (feux de circulation) peuvent être décrits comme suit:
La copie de code est la suivante:
var fsm = statemachine.create ({{
Initial: «vert»,
Événements: [
{nom: 'avertir', de: 'vert', à: 'jaune'},
{nom: 'stop', de: 'jaune', à: 'rouge'},
{nom: «prêt», de: «rouge», à: «jaune»},
{nom: 'Go', de: 'jaune', à: 'vert'}
]]
});
L'état initial du feu de circulation est vert. L'attribut des événements est divers événements qui déclenchent des changements d'état, tels que l'événement d'avertissement qui fait que l'état vert devient l'état jaune, l'événement d'arrêt fait que l'état jaune devient un état rouge, etc.
Après avoir généré l'instance, vous pouvez interroger l'état actuel à tout moment.
La copie de code est la suivante:
* FSM.Current: renvoie le statut actuel.
* FSM.IS (S): Renvoie une valeur booléenne indiquant si l'état est l'état actuel.
* FSM.Can (E): Renvoie une valeur booléenne indiquant si l'événement E peut être déclenché à l'état actuel.
* FSM.Cannot (E): Renvoie une valeur booléenne indiquant si l'événement E ne peut pas être déclenché dans l'état actuel.
JavaScript Finite State Machine permet de spécifier deux fonctions de rappel pour chaque événement, en prenant l'événement d'avertissement à titre d'exemple:
La copie de code est la suivante:
* OnBeforewarn: déclenché avant que l'événement d'avertissement ne se produise.
* onafterwarn (peut être abrégé en onwarn): déclenché après que l'événement de guerre se produit.
Dans le même temps, il permet également de spécifier deux fonctions de rappel pour chaque état, en prenant l'état vert comme exemple:
La copie de code est la suivante:
* OnLeaveen: déclenché lors de la sortie de l'état vert.
* onentergreen (peut être abrégé sous forme d'Ongreen): déclenché lors de l'entrée à l'état vert.
En supposant que l'événement Warn change l'état du vert au jaune, les quatre types de fonctions de rappel ci-dessus se produisent dans l'ordre suivant: OnBeforewarn → OnLeaveen → ONENERYELOKEL → Onafterwarn.
En plus de spécifier une fonction de rappel pour chaque événement et l'état séparément, vous pouvez également spécifier une fonction de rappel commune pour tous les événements et états.
La copie de code est la suivante:
* OnBeforeEvent: déclenché avant tout événement.
* OnLeAVeTate: déclenché lors de la sortie d'un état.
* ONENERSTATE: déclenché lors de la saisie de n'importe quel état.
* OnafterEvent: déclenché après la fin de l'un ou l'autre événement.
S'il existe des opérations asynchrones dans la fonction de rappel de l'événement (comme la communication Ajax avec le serveur), nous pouvons vouloir attendre que l'opération asynchrone ne soit terminée avant que les modifications de l'État ne se produisent. Cela nécessite la méthode de transition.
La copie de code est la suivante:
fsm.onwarn = function () {
Light.fadeout ('Slow', fonction () {
fsm.transition ();
});
retour stateMachine.async;
};
Dans la fonction de rappel dans le code ci-dessus, il y a une opération asynchrone (Light.fadeout). Si vous ne voulez pas que l'état change immédiatement, vous devez laisser la fonction de rappel renvoyer un objet StateMachine.async, indiquant que l'état ne change pas pour le moment; Attendez que l'opération asynchrone soit terminée, puis appelez la méthode de transition pour faire changer l'état.
JavaScript Finite State Machine permet également de spécifier les fonctions de traitement des erreurs qui sont automatiquement déclenchées lorsque des événements qui sont impossibles à se produire dans l'état actuel.
La copie de code est la suivante:
var fsm = statemachine.create ({{
// ...
Erreur: fonction (Eventname, From, to, args, errorcode, errorMessage) {
return 'Event' + EventName + ':' + errorMessage;
},
// ...
});
Par exemple, l'état actuel est vert et théoriquement, seul un événement d'avertissement peut se produire pour le moment. Si un événement d'arrêt se produit pour le moment, la fonction de gestion des erreurs ci-dessus sera déclenchée.