我们昨天透过一个 object 描述一个状态机的定义,还记得前天我们的 switch / case
做出的 transition function 吗?transition function 是一个 纯函式(pure function),我们还缺少一个东西来储存当前的状态。
State Machine 不完全,没有一个变数能帮我记忆当下的状态是什麽,我在使用 transition 时还要另外用一堆变数来储存 state ,感觉不好维护、也不好维持程序码的连贯性
试着思考看看 有个 function 叫做 createMachine
,当我们把 状态机的定义 machineDef
丢进去,他就可以回传给我们一个能储存状态的状态机
someMachine = createMachine(someMachineDef)
那我们这个 someMachine 会需要有哪些东西?
by The Finite State of Reactive Animations
[x] Initial State,
[x] States,
[x] Events,
[_] Transition,
[_] Final States (可能没有)
上面 [x] 这些东西已经在昨天被我们写进 machineDef
,那我们应该还缺的是 transition function 跟能储存当下状态的 Current State
为了储存状态 Current State,程序开发中,目前所知具有状态性,能储存状态的值也是「物件」,所以我们决定采用物件,这个物件会依照 machineDef
当作 configuration。
假设我们希望 someMachine.state
可以拿到当前状态, someMachine.transition('事件')
可以转移状态,所以我们的透过 function 回传一个物件,实作可以长这样
function createMachine(machineDef) {
return {
// 初始值是 initialState 我们透过这个 object 储存 state
state:machineDef.initialState,
// 实作 transition
transition(event){
...
}
}
}
那新版的 transition 该怎麽实作,先来看看我们手上有什麽材料,一起来看看昨天的 machineDef
const machineDef = {
initialState: "站姿、静止",
states: {
"站姿、静止": {
on: {
跳跃: "跳跃中",
.....
我们可以从 machineDef.states[state]
拿到当前状态下所有事件对应该的转换,下个也就是我们昨天说的那个名为 on 的 transition mapping
所以继续往下走,接着可以透过 machineDef.states[state].on[event]
,取得发生某个的事件後要转成的状态。
所以我们的 transition
应该可以这样实作,拿到物件的 Current State ,以及使用者要执行的事件 Event
transition(event){
const nextState = machineDef.states[this.state]?.on[event]
this.state = nextState
return this.state
}
然後可能查找失败,当我们拿不到值,transition 不能正确转换、或说不应该转换,此时,我们应该就要维持原本的状态
因为 nextState = transition(previousState, event)
的 previusState, event,只要其中一个是不符的话,代表我们不能改变状态。
transition(event){
const nextState = machineDef.states[this.state]?.on[event]
if(nextState){
this.state = nextState
}
return this.state
}
如此我们就完成了一个简单的 state machine
function createMachine(machineDef) {
return {
// 初始值是 initialState 我们透过这个object 储存 state
state:machineDef.initialState,
// 实作 transition
transition(event){
const nextState = machineDef.states[this.state]?.on[event]
if(nextState){
this.state = nextState
}
return this.state
}
}
}
<<: 【Day25】React Class Component 生命周期简单介绍
tags: OC 30 day 为什麽放这张图?应为我觉得MRC就像是古老的仪式。既然MRC已经没什...
终於要进入 Celery 这个主题了,还记得我在 Day 24 说过介绍 Flask-Mail 的另...
高中听过有人念ㄙㄨㄟˊ 圆形,我当时真是害怕极了。 --- 椭圆曲线 (Elliptic curve...
大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...
接续上一次的内容,今天一样会用较为简单的叙述去介绍与分享SQL的简易语法与函数。(大写为内建语法) ...