在平时的工作中,有时候我们会遇到需要处理诸多状态的情况,譬如订单状态,简单罗列就有12种状态
"0": "交易关闭",
"1": "待支付",
"2": "支付确认中",
"3": "支付中",
"4": "待收货",
"5": "交易成功", // 已签收
"-1": "交易关闭", // 订单已取消
"-2": "交易关闭,退款中",
"-3": "交易关闭,已退款",
"-4": "订单异常",
"-5": "退货退款中",
"-6": "已退货退款"
复制代码
而且这些状态之间存在联系。比如待支付状态下一个可能是支付确认中,可能是交易关闭,也可能是交易成功。
如何处理这么多的状态以及之间的关系,我们需要一个状态管理的机制,来统一处理,这里就需要FSM.
FSM概念
FSM(finite-state machine):表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型
FSM-3特点
- 一个时刻,只有一个状态。
- 某种条件下,会从一种状态转变(transition)到另一种状态。(比如待支付的下个状态是支付成功)
- 状态有限(finite)
FSM-4要素(记住这个就可以了)
- currentState(当前状态)
- nextState(下一个状态)
- transition(currentState,action)。当前状态和下个状态的关系。接收当前的状态,根据不同的action返回不同的nextState.
- action.state变动的event
红绿灯例子。
1.定义好三者切换状态。其中cd0,cd1,cd2。表示不同的倒计时,也就是触发状态变动的action.
const machine = {
green: {
cd0: 'yellow'
},
yellow: {
cd1:'red'
},
red: {
cd2: 'green'
}
};
复制代码
2. 定义transition
function transition(action) {
let nextState= machine[currentState][action];
render(nextState);
currentState= nextState;
return nextState;
}
复制代码
3. 定义render函数,根据当前的state,渲染不同颜色的灯
function render(state){
//do some render
}复制代码
完整的代码请看codepen.io/xff1874/pen…
FSM与redux
熟悉redux的开发者看到这里应该已经十分熟悉,redux的很多思想和这个FSM非常相似。
其中reducer扮演了transition的角色。为了防止mutation副作用,reducer必须是纯函数。
redux只是做状态的管理,react就是fsm render函数,负责更新view.
优缺点
优点
1. 状态管理高度可预测。
2. 单元测试。
3. 扩展性良好
4. 组件的实现和关系分离。避免了硬编码,组件之间关系就有JSON对象来维护。如果把yellow,green,red三者看做三个组件。那么他们之间的关系就有machine这个对象来维护。
缺点
1. 只适合复杂的状态,简单if else即可完成。
2.状态定义一定要清晰。
参考: