有人知道状态机的任何javascript实现吗?我的目标是设置一个状态机实现,将事件绑定到状态转换。因此,如果用户单击按钮,则状态将被更改,并且此状态可能会定义要更改的对象中的某些值。
我希望这是一个状态机,因为会有一个规则json文件,它允许在调用某些事件时指示各种对象的值发生了什么变化。因为这将在文件中构建,我认为很容易将该信息解析为状态机对象。
js中有两个用于有限状态机的主库:
1 / Machina:非常好的文档,示例,支持两个开箱即用的JavaScript消息总线提供程序:postal.js和amplify.js。
2 / Javascript State Machine:更简单,更易于使用,非常适合“基本”用法。
新库出来:https://github.com/jml6m/fas-js - 简单易用
README中也有一个演示。
我最近在JS中构建了一个状态机实现,由于其转换DSL,它当然是最容易配置的:
transitions: [
'next : intro > form > finish',
'back : intro < form < error',
'error : form > error',
'restart : intro < finish'
]
它在配置和事件处理程序分配方面都非常灵活,您可以在运行时添加和删除状态,暂停和恢复转换,挂钩大量事件,使用jQuery的帮助程序和Vue等反应框架:
文档和一大堆演示在这里:
我的状态机的一点点推广:stateflow我刚创建了自己的状态机,因为我发现没有一个对我来说足够简单。
使用js对象定义流,其中属性是状态名称,值是具有以下属性的另一个js对象。
简单的例子
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查看
试着看一下https://github.com/steelbreeze/state.js - 它支持UML 2规范中描述的大部分状态机语义,同时仍然具有高性能。文档的方式还不多,但是示例和测试应该提供一个很好的参考。
我选择了js-fsm微库。
特征
我以为我也会谈论自己的状态机库。两年前我来到这个问题,找不到符合我要求的任何东西,所以我写了state-transducer。
API的主要目标是:
它用于modelize user interfaces,改变用户流量
进入国家机器
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' />
还有一个检查员可以看到您的机器工作方式(随着时间旅行),例如: