跳到內容
關於我 數位花園

[考察] 有限狀態機

TypeScript 提供型別檢查;XState 則控制流程邏輯檢查 1

  • id: machine identifier
  • initial: initial state
  • context object: local context for entire machine
  • states object: state definitions
  • actions: the mapping of action names to their implementation
  • delays: the mapping of delay names to their implementation
  • guards: the mapping of transition guard (cond) names to their implementation
  • services: the mapping of invoked service (src) names to their implementation
  • activities (deprecated): the mapping of activity names to their implementation
  • atomic
  • compound
  • parallel
  • final
  • history

Transient state nodes are useful for determining which state the machine should really go to from a previous state based on conditions. They are most similar to choice pseudostates in UML.

The best way to define a transient state node is as an eventless state, and an always transition. This is a transition where the first condition that evaluates to true is immediately taken.

An event is what causes a state machine to transition from its current state to its next state.

「事件」使舊狀態轉移到新狀態

const timerEvent = {
type: "TIMER", // the convention is to use CONST_CASE for event names
};
// equivalent to { type: 'TIMER' }
const timerEvent = "TIMER";
const keyDownEvent = {
type: "keydown",
key: "Enter",
};

Transitions define how the machine reacts to events.

轉換定義了狀態機對發出的事件,要做什麼反應。

Transition 的兩個參數:

  • state:轉換的狀態
  • event:轉換觸發的事件
const lightMachine = createMachine({
/* ... */
});
const greenState = lightMachine.initialState;
// determine next state based on current state and event
const yellowState = lightMachine.transition(greenState, { type: "TIMER" });
console.log(yellowState.value);
// => 'yellow'

In statecharts, states can be nested within other states. These nested states are called compound states.

A parallel state node is specified on the machine and/or any nested compound state by setting type: 'parallel'.

XState 狀態機:紅綠燈(簡易版)

Section titled “XState 狀態機:紅綠燈(簡易版)”
import { createMachine, interpret } from "xstate";
type TrafficLightEvent = { type: "NEXT" };
type TrafficContext = undefined;
type TrafficLightState =
| { context: undefined; value: "green" }
| { context: undefined; value: "yellow" }
| { context: undefined; value: "red" };
export const trafficLightMachine = createMachine<TrafficContext, TrafficLightEvent, TrafficLightState>({
id: "trafficLight",
initial: "red",
states: {
green: {
on: { NEXT: "yellow" },
},
red: {
on: { NEXT: "green" },
},
yellow: {
on: { NEXT: "red" },
},
},
});
  1. TypeScript gives you type safety, and XState gives you logical safety.