状态机

前言

我们常常说在前端框架中使用状态机管理全局状态,这个时候状态机一般指redux、vuex等库。但事实上,redux和vuex并不是真正的状态机。今天让我们来了解下状态机。

有限状态机

首先,我们需要明确概念,什么是状态机:w3c状态机介绍

Each state contains a set of transitions that define how it reacts to events. Events can be generated by the state machine itself or by external entities. In a traditional state machine, the machine is always in a single state. This state is called the active state. When an event occurs, the state machine checks the transitions that are defined in the active state. If it finds one that matches the event, it moves from the active state to the state specified by the transition (called the "target" of the transition.) Thus the target state becomes the new active state.

每个状态都包含一组定义它如何对事件做出反应的转换。事件可以由状态机本身或外部实体生成。在传统的状态机中,机器始终处于单一状态。这种状态称为活动状态。当事件发生时,状态机会检查在活动状态中定义的转换。如果它找到一个与事件匹配的状态,它就会从活动状态移动到由转换指定的状态(称为转换的“目标”)。因此,目标状态成为新的活动状态。

也就是说状态机管理着一个变量,这个变量有多个状态。在不同状态下,可以执行的行为不同。而状态机会接收事件改变状态。

Redux

我们再来简单介绍下Redux原理以及为什么它不是状态机。

Redux机制非常简单:一个状态树,一个用户定义的Reducer函数,一个Disptch用于触发Reducer,还有一个观察者subscribe用于获取更新后的值。

// 部分魔改源码
// redux/src/createStore.ts

export default function createStore(reducer, initState) {
  let currentState = initState
  let Listeners = []
  
  function getState() {return currentState}
  function dispatch(action) {
    currentState = reducer(currentState, action)
    Listeners.forEach(listen => listen())
  }
  function subscribe(listener) {
    Listeners.push(listener)
    return function unsubscribe() {
      const index = nextListeners.indexOf(listener)
      nextListeners.splice(index, 1)
    }
  }
  return {
    dispatch,
    subscribe,
    getState,
  }
}

与状态机概念最大不同的是:

Redux没有对Reducer函数做限制,所以不满足状态与行为之间的约束关系。

XState

XState是根据状态机标准的全局状态管理库。XState还提供了可视化的状态管理,即状态图。

用法:

import { createMachine, interpret } from 'xstate';

// Stateless machine definition
// machine.transition(...) is a pure function used by the interpreter.
const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: { on: { TOGGLE: 'active' } },
    active: { on: { TOGGLE: 'inactive' } }
  }
});

// Machine instance with internal state
const toggleService = interpret(toggleMachine)
  .onTransition((state) => console.log(state.value))
  .start();
// => 'inactive'

toggleService.send('TOGGLE');
// => 'active'

toggleService.send('TOGGLE');
// => 'inactive'

参考

xstate作者对比redux与xstate

redux源码

redux源码分析

有限状态机 wiki

XState:都1202年了,不会真有人还在用假的状态管理库吧?

你可能感兴趣的:(状态机)