Einfach ausgedrückt hat es drei Eigenschaften:
* Die Gesamtzahl der Staaten (Staat) ist begrenzt.
* Zu jedem Zeitpunkt befinden Sie sich nur in einem Zustand.
* Unter bestimmten Voraussetzungen kommt es zu einem Übergang von einem Zustand in einen anderen.
Für JavaScript bedeutet es, dass viele Objekte als Finite-State-Maschinen geschrieben werden können.
Zum Beispiel gibt es auf der Webseite ein Menüelement. Wenn Sie mit der Maus darüber schweben, wird das Menü angezeigt. Wenn Sie die Maus wegbewegen, wird das Menü ausgeblendet. Wenn zur Beschreibung eine endliche Zustandsmaschine verwendet wird, verfügt dieses Menü nur über zwei Zustände (Anzeigen und Ausblenden), und die Maus löst einen Zustandsübergang aus.
Der Code kann wie folgt geschrieben werden:
var menu = {
// Aktueller Status
currentState: 'hide',
// Ereignis binden
initialize: function() {
var self = this;
self.on("hover ", self.transition);
},
// Zustandsübergang
Transition: function(event){
switch(this.currentState) {
case "hide":
This.currentState = 'show';
doSomething();
case "show":
doSome thing();
break;
default:
console.log ('Ungültiger Zustand!');
break;
}
}
};
Wie Sie sehen können, verfügt die Schreibmethode der Finite-State-Maschine über eine klare Logik und eine starke Ausdruckskraft, was der Kapselung von Ereignissen förderlich ist. Je mehr Zustände ein Objekt hat und je mehr Ereignisse auftreten, desto geeigneter ist die Verwendung von Finite-State-Machine-Schreiben.
Darüber hinaus ist die JavaScript-Sprache eine Sprache mit vielen asynchronen Vorgängen. Eine gängige Lösung besteht darin, eine Rückruffunktion anzugeben, was jedoch zu Problemen wie einer verwirrenden Codestruktur und Schwierigkeiten beim Testen und Debuggen führt. Finite-State-Maschinen bieten eine bessere Möglichkeit: Verknüpfen Sie die asynchrone Operation mit der Zustandsänderung des Objekts. Wenn die asynchrone Operation endet, erfolgt die entsprechende Zustandsänderung, die andere Operationen auslöst. Dies ist logisch sinnvoller und lässt sich die Komplexität des Codes einfacher reduzieren als Lösungen wie Rückruffunktionen, Ereignisüberwachung und Veröffentlichung/Abonnement.
Im Folgenden wird eine Finite-State-Machine-Funktionsbibliothek mit Javascript-Finite-State-Machine vorgestellt. Diese Bibliothek ist sehr leicht zu verstehen und kann uns helfen, unser Verständnis zu vertiefen, und ihre Funktionen sind überhaupt nicht schwach.
Diese Bibliothek stellt ein globales Objekt StateMachine bereit. Mit der Erstellungsmethode dieses Objekts können Sie eine Instanz einer endlichen Zustandsmaschine generieren.
Code kopieren
Beim Generieren müssen Sie ein Parameterobjekt bereitstellen, um die Art der Instanz zu beschreiben. Eine Ampel (Ampel) kann beispielsweise so beschrieben werden:
Code kopieren
Ereignisse: [
{ Name: 'warn', von: 'grün', bis: 'gelb' },
{ Name: ' Stop', von: 'Gelb', bis: 'Rot' },
{ Name: 'bereit', von: 'Rot', bis: 'Gelb' },
{ Name: 'Los', von : 'gelb', zu: 'grün' }
]
});
Der Anfangszustand der Ampel ist grün, und das Ereignisattribut enthält die verschiedenen Ereignisse, die den Zustandswechsel auslösen. Beispielsweise ändert das Warnereignis den grünen Zustand in den gelben Zustand, das Stoppereignis ändert den gelben Zustand der rote Zustand und so weiter.
Nach dem Generieren einer Instanz können Sie jederzeit den aktuellen Status abfragen.
Code kopieren
Der Code lautet wie folgt: * fsm.current: Gibt den aktuellen Status zurück . * fsm.is(s): Gibt einen booleschen Wert zurück, der angibt, ob Zustand s der aktuelle Zustand ist. * fsm.can(e): Gibt einen booleschen Wert zurück, der angibt, ob Ereignis e im aktuellen Zustand ausgelöst werden kann.
* fsm.cannot(e): Gibt einen booleschen Wert zurück, der angibt, ob Ereignis e im aktuellen Zustand nicht ausgelöst werden kann.
Javascript Finite State Machine ermöglicht es Ihnen, für jedes Ereignis zwei Rückruffunktionen anzugeben, am Beispiel des Warnereignisses:
* onbeforewarn: Wird ausgelöst, bevor das Warnereignis auftritt .
* onafterwarn (kann als onwarn abgekürzt werden): Wird ausgelöst, nachdem das Warnereignis auftritt.
Gleichzeitig ist es auch möglich, für jeden Zustand zwei Rückruffunktionen anzugeben, am Beispiel des grünen Zustands:
* onleavegreen: Wird beim Verlassen des grünen Zustands ausgelöst .
* onentergreen (kann als ongreen abgekürzt werden): Wird beim Eintritt in den grünen Zustand ausgelöst.
Unter der Annahme, dass das Warnereignis den Status von Grün auf Gelb ändert, ist die Reihenfolge des Auftretens der oben genannten vier Arten von Rückruffunktionen wie folgt: onbeforewarn → onleavegreen → onenteryellow → onafterwarn.
Zusätzlich zur Angabe separater Rückruffunktionen für jedes Ereignis und jeden Status können Sie auch eine gemeinsame Rückruffunktion für alle Ereignisse und Status angeben.
* onbeforeevent: Wird ausgelöst, bevor ein Ereignis eintritt.
* onleavestate: Wird beim Verlassen eines beliebigen Staates ausgelöst.
* onenterstate: Wird beim Eintritt in einen beliebigen Zustand ausgelöst.
* onafterevent: Wird nach dem Ende eines Ereignisses ausgelöst.
Wenn die Ereignisrückruffunktion einen asynchronen Vorgang enthält (z. B. Ajax-Kommunikation mit dem Server), möchten wir möglicherweise warten, bis der asynchrone Vorgang endet, bevor sich der Status ändert. Dies erfordert die Verwendung der Übergangsmethode.
fsm.onwarn = function(){
light .fadeOut('slow', function() {
fsm.transition();
});
return StateMachine.ASYNC;
};
In der Rückruffunktion des obigen Codes gibt es eine asynchrone Operation (light.fadeOut). Wenn Sie nicht möchten, dass sich der Status sofort ändert, müssen Sie die Rückruffunktion ein StateMachine.ASYNC-Objekt zurückgeben lassen, das angibt, dass sich der Status vorübergehend nicht ändert. Warten Sie, bis der asynchrone Vorgang abgeschlossen ist, und rufen Sie dann die Übergangsmethode auf Zustand zu ändern.
Javascript Finite State Machine ermöglicht Ihnen außerdem die Angabe einer Fehlerbehandlungsfunktion, die automatisch ausgelöst wird, wenn ein Ereignis eintritt, das im aktuellen Zustand nicht eintreten kann.
var fsm = StateMachine.create({
/ / ...
error: function(eventName, from, to, args, errorCode, errorMessage) {
return 'event ' eventName ': ' errorMessage;
},
// ...
});
Wenn der aktuelle Status beispielsweise grün ist, kann zu diesem Zeitpunkt theoretisch nur ein Warnereignis auftreten. Wenn zu diesem Zeitpunkt ein Stoppereignis auftritt, wird die obige Fehlerbehandlungsfunktion ausgelöst.