JavaScript中的状态模式

194 阅读2分钟

介绍

※ 一个对象有状态变化

※ 每次状态变化都会触发一个逻辑

※ 不能总是用 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

github.com/jakesgordon…

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;
}

设计原则

● 将状态对象和主题对象分离,状态的变化逻辑单独处理

● 符合开放封闭原则