Modo de estado
- Un objeto tiene un cambio de estado
- Cada cambio de estado desencadena una lógica
- No siempre puedes
if ... else
ser controlado
Ejemplo
de semáforos
Diagrama de clases UML tradicional
Diagrama UML simple en versión JS:
// 状态: 红灯 黄灯 绿灯
class State {
constructor(color) {
this.color = color
}
handle(context) {
console.log(`turn to ${
this.color} light`)
context.setState(this)
}
}
// 主体
class Context {
constructor() {
this.state = null
}
getState() {
return this.state
}
setState(state) {
this.state = state
}
}
// test
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()) // 打印状态
// 红灯亮了
red.handle(context)
console.log(context.getState()) // 打印状态
// 黄灯亮了
yellow.handle(context)
console.log(context.getState()) // 打印状态
输出:
turn to green light
State {
color: 'green' }
turn to red light
State {
color: 'red' }
turn to yellow light
State {
color: 'yellow' }
Escenas
- Máquina de estados finitos
- Escribe una promesa simple
Máquina de estados finitos
- Un número finito de estados, y los cambios entre estos estados
- Como semáforos
- Utilice lib de código abierto: javascript-state-machine
https://github.com/jakesgordon/javascript-state-machine
// 状态机模型
const fsm = new StateMachine({
init: '收藏', // 初始状态,待收藏
transitions: [
{
name: 'doState',
from: '收藏',
to: '取消收藏'
},
{
name: 'deleteStore',
from: '取消收藏',
to: '收藏'
}
],
methods: {
// 监听执行收藏
onDoStore: function() {
alert('收藏成功') // 可以放post请求
updateText()
},
// 监听取消收藏
onDeleteStore: function() {
alert('已取消收藏') // 可以放post请求
updateText()
}
}
})
const $btn = ${
'#btn'}
// 点击事件
$btn.click(function () {
if (fsm.is('收藏')) {
fsm.doStore()
} else {
fsm.deleteStore()
}
})
// 更新文案
funciton updateText() {
$btn.text(fsm.state)
}
// 初始化文案
updateText()
Escribe una promesa simple
La promesa es una máquina de estados finitos
- La promesa tiene tres estados: pendiente cumplida rechazada
- pendiente -> cumplido 或者 pendiente -> rechazado
- No se puede revertir el cambio
// 模型
const fsm = new StateMachine({
init: 'pending',
transitions: [
{
name: 'resolve',
from: 'pending',
to: 'fullfilled'
},
{
name: 'reject',
from: 'pending',
to: 'rejected'
}
],
methods: {
// 成功
onResolve: function (state, data) {
// 参数: state - 当前状态示例: data - fsm.resolve(xxx) 执行传递过来的参数
data.successList.forEach(fn => fn())
},
// 失败
onReject: function (state, data) {
// 参数: state - 当前状态示例: data - fsm.reject(xxx) 执行传递过来的参数
data.failList.forEach(fn => fn())
}
}
})
// 定义Promise
class MyPromise {
constructor(fn) {
this.successList = []
this.failList = []
fn(() => {
// resolve函数
fsm.resolve(this)
}, () => {
// reject 函数
fsm.reject(this)
})
}
then(successFn, failFn) {
this.successList.push(successFn)
this.failList.push(failFn)
}
}
// test
function loadImg(src) {
const promise = new MyPromise(function(resolve, reject) {
let img = document.createElement('img')
img.onload = function () {
resolve(img)
}
img.onerror = function () {
reject()
}
img.src = src
})
return promise
}
let src = "xxx.png"
let result = loadImg(src)
result.then(function () {
console.log('ok1')
}, function () {
console.log('fail1')
})
result.then(function () {
console.log('ok2')
}, function () {
console.log('fail2')
})
Verificación del principio de diseño
- Separe el objeto de estado del objeto de sujeto y maneje la lógica de cambio de estado por separado
- Cumplir con el principio abierto y cerrado.