SOURCE

console 命令行工具 X clear

                    
>
console
const bulb = document.getElementById("bulb");
const status = document.getElementById("status");

function StateMachine(config) {
    // 初始化
    const machine = { ...config };
    if (!machine.initial) {
        machine.initial = {};
    }
    if (!machine.initial.action) {
        machine.initial.action = () => { }
    }
    machine.value = machine.initial.value;
    machine.initial.action();

    // 当触发transfer时,遍历状态机,获取下一个状态,并执行对应action
    machine.states = machine.states || [];
    machine.transfer = (curState = { value: "" }, event) => {
        let nextState = curState;
        for (let i = 0; i < machine.states.length; i++) {
            if (machine.states[i].name === event && machine.states[i].from === curState.value) {
                nextState.value = machine.states[i].to || "";
                machine.value = nextState.value;
                nextState.action = machine.states[i].action || function () { };
                nextState.action();
                break;
            }
        }
        return nextState;
    }

    return machine;
}

// 测试
// UI改变函数light
function light() {
    bulb.className = "light";
    status.innerText = "on";
}
// UI改变函数dark
function dark() {
    bulb.className = "dark";
    status.innerText = "off";
}
const fsm = new StateMachine({
    initial: {
        value: "off",
        action: function () {
            bulb.className = "dark";
            status.innerText = "off";
        }
    },
    states: [
        { name: "turnOn", from: "off", to: "on", action: light },
        { name: "turnOff", from: "on", to: "off", action: dark },
    ]
});

// 获取初始化状态
const { initial } = fsm;
let curState = { ...initial };
// 函数改变状态
function turnOnClick() {
    curState = fsm.transfer(curState, "turnOn");
    console.log(fsm.value);
}
function turnOffClick() {
    curState = fsm.transfer(curState, "turnOff");
    console.log(fsm.value);
}
<div id="bulb">
    <div></div>
    <div></div>
    <div></div>
</div>
<br>
<button onclick="turnOnClick()">turnOn</button>
<button onclick="turnOffClick()">turnOff</button>

<div>status:
    <span id="status"></span>
</div>
.dark>div:first-child, .light>div:first-child{
    width: 50px;
    height: 50px;
    border-radius: 50%;
    overflow: hidden;
    background: #ccc;
}
.dark>div:nth-child(2), .light>div:nth-child(2){
    width: 18px;
    height: 30px;
    border-radius: 50%;
    margin-left: 15px;
    margin-top: -18px;
    background: #ccc;
}
.dark>div:nth-child(3), .light>div:nth-child(3){
    width: 15px;
    height: 15px;
    border-radius: 50%;
    margin-left: 16.5px;
    margin-top: -10px;
    background: #ccc;
}

.light>div:first-child, .light>div:nth-child(2){
    background: #fbff03;
}

.light>div:nth-child(3){
    background: #333;
}