介绍
※ 一个对象有状态变化
※ 每次状态变化都会触发一个逻辑
※ 不能总是用 if..else 来控制
实现代码(ES6)
//状态 (红灯、绿灯、黄灯)
class State{
constructor(color){
this.color = color
}
handle(context){
console.log(`turn ro ${this.color} light`)
//设置状态
context.setState(this)
}
}
//主体
class Context {
constructor(){
this.state = null
}
//获取状态
getState(){
return this.state
}
setState(state){
this.state = state;
}
}
let context = new Context();
let green = new State('green')
let yellow = new State('yellow')
let red = new State('red')
green.handle(context)
console.log(context.getState())
yellow.handle(context)
console.log(context.getState())
red.handle(context)
console.log(context.getState())
举个栗子
● 交通信号灯
有限状态机
◆ 有限个状态,以及在这些状态之间的变化
◆ 如交通信号灯
◆ 使用开源 lib : javascript-state-machine
javascript-state-machine使用示范
import StateMachine from 'javascript-state-machine'
//初始化状态机模型
var fsm = new StateMachine({
init: '收藏',
transitions: [
{ name: 'doStore', from: '收藏', to: '取消收藏' },
{ name: 'deleteStore', from: '取消收藏', to: '收藏' },
],
methods: {
onDoStore: function () {
alert('收藏成功') //这里可以发送POST请求
updateText()
},
onDeleteStore: function () {
alert('取消收藏成功')
updateText()
},
}
});
let btn = document.getElementById('btn')
btn.addEventListener('click',function(){
if(fsm.is('收藏')){
fsm.doStore()
}else{
fsm.deleteStore()
}
})
//更新按钮的文案
function updateText() {
btn.innerText(fsm.state)
}
//初始化文案
updateText()
Promise 就是有限状态机
◆ Promise 三种状态 : pending fullfilled rejected
◆ pending => fullfilled 或者 pending => rejected
◆ 不能逆向变化
import StateMachine from 'javascript-state-machine'
//初始化状态机模型
let fsm = new StateMachine({
init: 'pending', //初始化状态
transitions: [
{
name: 'resolve', //事件名称
from: 'pending',
to: 'fullfilled'
},
{
name: 'reject', //事件名称
from: 'pending',
to: 'rejected'
},
],
methods: {
//监听 resolve
onResolve: function (state,data) {
// state - 当前状态机实例; data - fsm.resolve(xxx) 传递的参数
data.succesList.forEach(fn => fn())
},
//监听 reject
onReject: function (state,data) {
// statte - 单曲状态机实例; data -fsm.reject(xxx) 传递的参数
data.failList.forEach(fn => fn())
},
}
});
class MyPromise {
constructor(fn){
this.succesList = []
this.failList = []
fn(function(){
fsm.resolve(this)
},function(){
fsm.reject(this)
})
}
then(succesFn,failFn){
this.succesList.push(succesFn)
this.failList.push(failFn)
}
}
//测试代码
function loadImg(src){
const promise = new Promise(function(resolve,reject){
let img = document.createElement('img');
img.onload = function(){
resolve(img)
}
img.onerror = function(){
reject()
}
img.src = src
})
return promise;
}
设计原则
● 将状态对象和主题对象分离,状态的变化逻辑单独处理
● 符合开放封闭原则