web-dev-qa-db-ja.com

JavaScriptイベントステートマシン

誰かがステートマシンのjavascript実装を知っていますか?私の目標は、イベントを状態遷移にバインドする状態マシン実装をセットアップすることです。したがって、ユーザーがボタンをクリックすると、状態が変更され、この状態によって、たとえば変更されるオブジェクトの特定の値が定義される場合があります。

特定のイベントが呼び出されたときにさまざまなオブジェクトのどの値が変化するかを指示できるルールjsonファイルがあるため、これをステートマシンにしたいのです。これはファイル内で構造化されるため、その情報をステートマシンオブジェクトに簡単に解析できると思います。

30
jab

Jsには、有限状態マシン用の2つの主要なライブラリがあります。

1/ Machina :非常によく文書化された例で、2つのJavaScriptメッセージバスプロバイダーがすぐに使用できます: postal.js および amplify.js

2/ Javascript State Machine :よりシンプルで使いやすく、「基本的な」使用に最適です。

34
Benibur

私は最近、遷移DSLのおかげで、JSでステートマシンの実装を構築しました。

transitions: [
  'next    : intro > form > finish',
  'back    : intro < form           < error',
  'error   :         form >           error',
  'restart : intro        < finish'
]

構成とイベントハンドラーの割り当ての両方で非常に柔軟性があり、実行時に状態を追加および削除したり、遷移を一時停止および再開したり、大量のイベントにフックしたり、Vueのようなリアクティブフレームワークを使用したりできます:

state-machine-demo

ドキュメントとデモのホストはこちら:

6
Dave Stewart

ステートマシンの少しの昇進:ステートフローステートマシンを作成したのは、自分にとって十分に単純なものが見つからなかったからです。

フローはjsオブジェクトで定義されます。プロパティは状態名で、値は次のプロパティを持つ別のjsオブジェクトです。

  • タイプ:開始、終了、または状態(デフォルト)。
  • action:これに設定されたStateインスタンスオブジェクトを持つ関数は、以前に登録されたactionまたはこの場合はサブフローである別のフロー定義とも呼ばれます。
  • on:プロパティはイベントに一致し、値はgotoの次の状態です

簡単な例

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);
});

Git https://github.com/philipdev/stateflow またはnpmで確認してください

4
philipdev

https://github.com/steelbreeze/state.js を見てみてください-UML 2仕様で説明されているステートマシンセマンティクスの多くをサポートしながら、パフォーマンスを維持しています。文書化の方法はまだあまりありませんが、例とテストを参考にしてください。

3
Mesmo

JQueryを使用して設計されたライブラリは、探していることを実行し、イベントを自動的にバインドしているように見えます。

2
user3109359

Js-fsmマイクロライブラリを使用してこれを選択します。

機能

  • 状態ベースのFSMの説明。および状態遷移の配列で構成される状態。
  • イベントからの移行。複数のイベントはORされたイベントを定義します。
  • 条件からの移行。条件は、条件オブジェクトで一致するキーと値のペアです。複数のキーと値のペアがAND条件を定義しました。複数の条件がOR条件を定義します
  • 各遷移は、オプションでアクションまたは複数のアクションを呼び出すことができます。アクションは、オプションで引数を持つか、このメンバーにすることができます。
  • ステートマシンは、既存のオブジェクトまたはコンストラクターのプロトタイプに(ミックスインとして)混在させることができます。この方法が提供されます。
  • ステートマシンは、オプションでログメソッドが存在する場合、または提供されている場合にログを記録できます。
  • AMDおよびNodeモジュールがサポートされています。
  • QUnitを使用した単体テスト。

js-fsm githubページ。

1
basos

自分のステートマシンライブラリについても話したいと思いました。私はこれに2年前にSOの質問に来て、私の要件に合うものを見つけることができなかったので、 state-transducer と書きました。

APIの主な目的は次のとおりです。

  • 内部状態がカプセル化された、機能的なAPI、完全に効果を欠いている
  • 一般性と再利用性(特定のユースケースまたはフレームワークに対応するための規定はありません)
  • 現在の設計の上に並行性および/または通信メカニズムを追加できる必要があります
  • react、Angularおよび一般的なフレームワークにスムーズに統合できる必要があります

ユーザーインターフェイスのモデル化 に使用され、ユーザーフローを切り替えます

user flow

ステートマシンに

fsm

1
user3743222

AsyncMachineは、JSのステートマシンに対するもう1つのオーソドックスなアプローチです(筆者です)。リレーショナルであり、同時にアクティブな複数の状態をサポートします。元の質問に答えるためのコードを次に示します。ボタンをクリックすると、コンテキストオブジェクトの新しい状態と属性に関する副作用があります。

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' />

また、マシンがどのように機能するかをタイムトラベルで視覚化できるインスペクターもあります。例:

enter image description here

0
Tobiasz Cudnik

次のライブラリを使用できます。

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

免責事項:私はそれを維持します。

0
Ben

新しいライブラリー出力: https://github.com/jml6m/fas-js -シンプルで使いやすい

READMEにもデモがあります。

0
JLewkovich