web-dev-qa-db-fra.com

Machine d'état d'événement JavaScript

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. 

28
jab

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".

30
Benibur

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:

state-machine-demo

Docs et une foule de démos ici:

5
Dave Stewart

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.

  • type: début, fin ou état (par défaut).
  • action: fonction avec un objet d'instance d'état défini sur ceci, peut également être nommée action précédemment enregistrée ou une autre définition de flux dans le cas présent il s'agit d'un sous-flux.
  • on: la propriété doit correspondre à l'événement et la valeur est l'état suivant à passer à 

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 

4
philipdev

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.

3
Mesmo

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:

2
user3109359

Mon choix à ce sujet avec la micro-bibliothèque js-fsm.

Caractéristiques

  • Description de FSM basée sur l'état. Un état composé d'un et d'un tableau de transitions d'état.
  • Transition des événements. Plusieurs événements définissent des événements ORed.
  • Transition des conditions. Une condition est une paire clé: valeur qui doit correspondre à l'objet de condition. Plusieurs clés, paires de valeurs définies dans des conditions ANDed. Plusieurs conditions définissent des conditions ORed
  • Chaque transition peut éventuellement appeler des actions ou plusieurs actions. Les actions peuvent éventuellement avoir des arguments ou en être membres.
  • La machine à états peut être mélangée (en tant que mixin) à un objet existant ou au prototype d'un constructeur. Une méthode pour cela est fournie.
  • La machine d'état peut éventuellement se connecter si une méthode de journalisation existe ou si elle est fournie.
  • Les modules AMD et Node sont pris en charge.
  • Tests unitaires avec QUnit.

page github js-fsm.

1
basos

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:

  • aPI fonctionnelle, entièrement dépourvue d'effet, à état interne encapsulé
  • généralité et possibilité de réutilisation (aucune disposition n'est prévue pour prendre en charge des cas d'utilisation ou des cadres spécifiques)
  • il doit être possible d'ajouter un mécanisme d'accès simultané et/ou de communication au-dessus de la conception actuelle
  • il doit être possible de s’intégrer en douceur dans React, Angular et votre framework populaire 

Il est utilisé pour modéliser les interfaces utilisateur , transformer les flux utilisateur

user flow

dans les machines d'état

fsm

1
user3743222

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:

 enter image description here

0
Tobiasz Cudnik

Vous pouvez trouver cette bibliothèque d'utilisation:

https://www.npmjs.com/package/mistic

Disclaimer: Je le maintiens.

0
Ben

Nouvelle bibliothèque out: https://github.com/jml6m/fas-js - simple et facile à utiliser

Il y a aussi une démo dans le README.

0
JLewkovich