JavaScript事件状态机

问题描述 投票:29回答:10

有人知道状态机的任何javascript实现吗?我的目标是设置一个状态机实现,将事件绑定到状态转换。因此,如果用户单击按钮,则状态将被更改,并且此状态可能会定义要更改的对象中的某些值。

我希望这是一个状态机,因为会有一个规则json文件,它允许在调用某些事件时指示各种对象的值发生了什么变化。因为这将在文件中构建,我认为很容易将该信息解析为状态机对象。

javascript state-machine
10个回答
32
投票

js中有两个用于有限状态机的主库:

1 / Machina:非常好的文档,示例,支持两个开箱即用的JavaScript消息总线提供程序:postal.jsamplify.js

2 / Javascript State Machine:更简单,更易于使用,非常适合“基本”用法。


0
投票

新库出来:https://github.com/jml6m/fas-js - 简单易用

README中也有一个演示。


5
投票

我最近在JS中构建了一个状态机实现,由于其转换DSL,它当然是最容易配置的:

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

它在配置和事件处理程序分配方面都非常灵活,您可以在运行时添加和删除状态,暂停和恢复转换,挂钩大量事件,使用jQuery的帮助程序和Vue等反应框架:

文档和一大堆演示在这里:


4
投票

我的状态机的一点点推广:stateflow我刚创建了自己的状态机,因为我发现没有一个对我来说足够简单。

使用js对象定义流,其中属性是状态名称,值是具有以下属性的另一个js对象。

  • type:begin,end或state(默认)。
  • action:将一个State实例对象设置为this的函数,也可以命名为先前已注册的action或另一个流定义,在这种情况下它是一个子流。
  • on:属性是匹配事件,值是下一个转到的状态

简单的例子

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查看


3
投票

试着看一下https://github.com/steelbreeze/state.js - 它支持UML 2规范中描述的大部分状态机语义,同时仍然具有高性能。文档的方式还不多,但是示例和测试应该提供一个很好的参考。


2
投票

1
投票

我选择了js-fsm微库。

特征

  • 基于状态的FSM描述。由a和一系列状态转换组成的状态。
  • 从事件过渡。多个事件定义ORed事件。
  • 从条件过渡。条件是一个键:值对应在条件对象上匹配。多个键,值对定义了ANDed条件。多个条件定义ORed条件
  • 每次转换都可以选择调用操作或多个操作。操作可以选择包含参数或成为其成员。
  • 状态机可以混合(作为mixin)到现有对象或构造函数的原型。提供了一种方法。
  • 状态机可以选择记录是否存在日志方法或提供日志方法。
  • 支持AMD和Node模块。
  • 使用QUnit进行单元测试。

js-fsm github page.


1
投票

我以为我也会谈论自己的状态机库。两年前我来到这个问题,找不到符合我要求的任何东西,所以我写了state-transducer

API的主要目标是:

  • 功能API,完全具有效果,具有封装的内部状态
  • 一般性和可重用性(没有为适应特定用例或框架而做出的规定)
  • 必须能够在当前设计之上添加并发和/或通信机制
  • 必须能够顺利地集成到React,Angular和您的流行框架中

它用于modelize user interfaces,改变用户流量

进入国家机器


0
投票

您可以找到这个使用库:

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

免责声明:我保留它。


0
投票

AsyncMachine是JS中另一种不太正统的状态机方法(我是作者)。它是关系型的,支持多个状态同时处于活动状态。这里有一些代码可以回答你的原始问题 - 单击按钮后,就新状态和上下文对象上的attr而言会产生副作用:

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

© www.soinside.com 2019 - 2024. All rights reserved.