Est-ce que quelqu'un connaît l'implémentation javascript d'une machine à états? Mon objectif est de configurer une implémentation de machine à états qui lierait les événements aux transitions d'état. Ainsi, si un utilisateur clique sur un bouton, l'état sera modifié et cet état peut définir certaines valeurs dans les objets à modifier, par exemple.
Je veux que ce soit une machine à états simplement parce qu'il y aura un fichier de règles json qui permettra de dicter quelles valeurs changent de divers objets lorsque certains événements sont appelés Comme cela sera structuré dans le fichier, je pense qu'il serait facile d'analyser ces informations dans un objet de machine à états.
Il existe deux bibliothèques principales pour une machine à états finis dans js:
1/ https://github.com/ifandelse/machina.js Des exemples très bien documentés prennent en charge deux fournisseurs de bus de messagerie JavaScript prêts à l'emploi: postal.js et amplify.js.
2/ https://github.com/jakesgordon/javascript-state-machine Plus simple et plus facile à utiliser, parfait pour les utilisations "de base".
J'ai récemment construit une implémentation de machine à états dans JS, qui est certainement la plus facile à configurer, grâce à sa transition DSL:
transitions: [
'next : intro > form > finish',
'back : intro < form < error',
'error : form > error',
'restart : intro < finish'
]
Il est vraiment flexible dans la configuration et dans l'affectation du gestionnaire d'événements. Vous pouvez ajouter et supprimer des états lors de l'exécution, des transitions de pause et de reprise, être accrochés à une tonne d'événements, avec des aides pour jQuery et des frameworks réactifs comme Vue:
Docs et une foule de démos ici:
Un peu de promotion pour ma machine d'état: stateflow Je viens de créer ma propre machine d'état parce que je n'en ai trouvé aucune qui soit assez simple pour moi.
un flux est défini avec un objet js où la propriété est le nom de l'état et la valeur est un autre objet js avec les propriétés suivantes.
Exemple simple
var stateflow = require('stateflow');
var flow = new stateflow.StateFlow({
a: {
type:'begin',
action: function(complete) {
// do something
complete('done');
},
on: {
done:'b',
again:'a'
}
},
b: {
type:'end',
action: function(complete) {
complete('finished');
}
}
});
flow.start(function(event) {
console.log('flow result:', event);
});
Découvrez-le sur git https://github.com/philipdev/stateflow ou via npm
Essayez de regarder https://github.com/steelbreeze/state.js - il prend en charge une grande partie de la sémantique de la machine à états décrite dans la spécification UML 2 tout en restant performant . la voie de la documentation pour le moment, mais les exemples et les tests devraient fournir une bonne référence.
Vous trouverez une bibliothèque conçue avec jQuery qui semble faire ce que vous cherchez et qui lie automatiquement les événements pour vous:
Mon choix à ce sujet avec la micro-bibliothèque js-fsm.
Caractéristiques
Je pensais parler de ma propre bibliothèque de machines d'état. Je suis arrivé à cette SO question il y a deux ans et je ne pouvais rien trouver qui réponde à mes exigences. J'ai donc écrit state-transducer .
Les principaux objectifs de l’API étaient les suivants:
Il est utilisé pour modéliser les interfaces utilisateur , transformer les flux utilisateur
dans les machines d'état
AsyncMachine est une autre approche moins orthodoxe de la machine à états dans JS (j'en suis l'auteur). C'est relationnel et supporte que plusieurs états soient actifs simultanément. Voici un code pour répondre à votre question initiale - après avoir cliqué sur le bouton, il y a des effets secondaires en termes de nouvel état et d'attr sur l'objet de contexte:
const {
machine
} = asyncmachine
// define states & relations
const state = {
Clicked: {
add: ['ShowFooter']
},
ShowFooter: {}
}
const example = machine(state)
// define handlers
example.Clicked_state = function() {
this.timeout = setTimeout(
this.dropByListener('Clicked'), 3000)
}
function render() {
console.log('render')
// get all the active state as class names
const classes = example.is().join(' ')
console.log(classes)
document.getElementById('content').innerHTML = `
<div class="${classes}">
<button>CLICK</button>
<footer>FOOTER</footer>
</div>
`
}
document.getElementById('content').addEventListener(
'click', example.addByListener('Clicked'))
// bind render to any state change
example.on('tick', render)
render()
.Clicked button {
background: red;
}
footer {
display: none;
}
.ShowFooter footer {
display: block
}
<script src="https://unpkg.com/[email protected]/dist/asyncmachine.umd.js"></script>
<div id='content' />
Un inspecteur peut également visualiser le fonctionnement de votre machine (avec un voyage dans le temps), par exemple:
Vous pouvez trouver cette bibliothèque d'utilisation:
https://www.npmjs.com/package/mistic
Disclaimer: Je le maintiens.
Nouvelle bibliothèque out: https://github.com/jml6m/fas-js - simple et facile à utiliser
Il y a aussi une démo dans le README.