Skip to content

并行状态

在状态图中,并行状态是具有多个子状态(也称为区域)的状态,这些子状态同时处于活动状态。这与父状态不同,在父状态中一次只有_一个_子状态处于活动状态。

并行状态具有以下特征:

  • 进入并行状态时,其所有区域也将同时进入。
  • 退出并行状态时,其所有区域也将同时退出。
  • 在并行状态中接收到的事件将同时被其所有区域接收和处理。

以下是一个具有并行状态的音乐播放器示例,其中包含两个区域,一个用于处理播放轨道,一个用于处理音量:

import { createMachine, assign } from 'xstate';

const playerMachine = createMachine({
id: 'player',
type: 'parallel',
states: {
track: {
initial: 'paused',
states: {
paused: {
on: { PLAY: 'playing' },
},
playing: {
on: { STOP: 'paused' },
},
},
},
volume: {
initial: 'normal',
states: {
normal: {
on: { MUTE: 'muted' },
},
muted: {
on: { UNMUTE: 'normal' },
},
},
},
},
});

并行状态值

并行状态的状态值是一个包含其每个区域状态值的对象。

const playerActor = createActor(playerMachine);
playerActor.start();

console.log(playerActor.getSnapshot().value);
// 输出对象:
// {
// track: 'paused',
// volume: 'normal'
// }

并行状态的 onDone 转换

当并行状态的所有区域都达到其最终状态时,将执行并行状态的 onDone 转换。

在此示例中,当两个区域都达到其最终状态时,将执行并行状态的 onDone 转换;也就是说,当 'grindingBeans' 达到 'grindingBeans.beansGround' 状态和 'boilingWater' 达到 'boilingWater.waterBoiled' 状态时。

import { createMachine } from "xstate";

export const machine = createMachine({
id: "coffee",
initial: "preparing",
states: {
preparing: {
states: {
grindBeans: {
initial: "grindingBeans",
states: {
grindingBeans: {
on: {
BEANS_GROUND: {
target: "beansGround",
},
},
},
beansGround: {
type: "final",
},
},
},
boilWater: {
initial: "boilingWater",
states: {
boilingWater: {
on: {
WATER_BOILED: {
target: "waterBoiled",
},
},
},
waterBoiled: {
type: "final",
},
},
},
},
type: "parallel",
onDone: {
target: "makingCoffee",
},
},
makingCoffee: {},
},
});

建模

即将推出

  • 避免区域之间的转换
  • 用于可能相互影响的关注点分离(即同步)
  • 如果完全独立,优先使用 invoke

并行状态备忘单

备忘单:创建并行状态

import { createMachine } from "xstate";

const machine = createMachine({
// ...
states: {
type: 'parallel',
states: {
one: {/* ... */},
two: {/* ... */},
three: {/* ... */}
},
onDone: {
// 当所有区域都达到其最终状态时执行
}
}
});