Skip to content

状态和转换

状态机帮助我们建模一个过程在事件发生时如何从一个状态转换到另一个状态。最基本的状态机由这些状态、事件和它们之间的转换组成。

状态

在 Stately 编辑器中,圆角矩形框表示状态。有几种不同类型的状态:

  • 普通状态没有任何特殊属性。
  • 初始状态 是机器启动时进入的第一个状态。
  • 最终状态 是机器在停止前进入的最后一个状态。
  • 父状态 可以包含更多状态,称为子状态。
  • 并行状态 是具有多个子状态的父状态,这些子状态同时处于活动状态。
  • 历史状态 是记住父状态退出时哪个子状态处于活动状态的父状态,并在重新进入父状态时重新进入该子状态。

你可以在状态上调用其他状态机或参与者,或在状态进入或退出时触发一个动作。阅读更多关于 Stately 编辑器中的动作和参与者

在 Stately 编辑器中,你还可以为状态添加描述颜色标签

创建状态

  • 双击画布上的任意位置以在那里创建一个新状态。
  • 选择一个现有状态并使用 子状态 在其中添加一个新状态。

删除状态

  • 使用 三点菜单或右键单击选定的状态,然后选择 删除 以删除选定的状态。
  • 使用 Backspace 键删除选定的状态。

父状态和子状态

状态可以包含更多状态,也称为子状态。只有在父状态处于活动状态时,这些子状态才处于活动状态。阅读更多关于父状态和子状态的信息

要添加子状态:

  • 选择一个现有状态并使用 子状态 在其中添加一个新状态。
  • 如果一个状态已经包含子状态,你可以双击父状态内部以创建另一个子状态。
  • 复制一个状态或一组状态和转换,并将它们粘贴到新的父状态上。
  • 通过选择子状态并从状态 详细信息 面板中选择一个新的父状态来重新设置子状态的父状态。

初始状态

当状态机启动时,它首先进入初始状态。在 Stately 编辑器中,带有箭头图标的实心圆表示初始状态。

机器只能有一个顶级初始状态。每个父状态都有自己的初始状态。如果你有无法到达的状态,可能是因为没有初始状态。阅读更多关于初始状态的信息

要将状态设置为初始状态:

  • 使用 三点菜单或右键单击一个状态,然后选择标记为初始状态。
  • 选择父状态,打开状态 详细信息 面板,并从 初始状态 菜单中选择所需的初始状态。

最终状态

当机器到达最终状态时,它将不再接收任何事件,内部运行的任何内容都将被取消和清理。

要将状态转换为最终状态:

  • 使用 三点菜单或右键单击一个状态,然后从 状态类型 中选择 最终状态
  • 选择状态,打开状态 详细信息 面板,并选择 最终 状态选项。

如果你希望机器在其最终子状态到达时从父状态转换,请使用状态完成事件

并行状态

在状态图中,并行状态是具有多个子状态(也称为区域)的状态,这些子状态同时处于活动状态。阅读更多关于并行状态的信息。每个区域都有虚线边框。

要将父状态转换为并行状态:

  • 使用 三点菜单或右键单击一个父状态,然后从 状态类型 中选择 并行状态
  • 选择父状态,打开状态 详细信息 面板,并选择 并行 状态选项。

历史状态

历史状态会记住其父状态退出前最后一个活动的子状态。当从父状态外部的转换目标指向历史状态时,会进入记住的子状态。阅读更多关于历史状态的信息。

  • 使用 三点菜单或右键单击一个状态,然后从 状态类型 中选择 历史状态
  • 选择父状态,打开状态 详细信息 面板,并选择 历史 状态选项。

无法到达的状态

警告图标表示无法到达的状态。状态无法到达是因为它没有通过转换连接到初始状态。

转换和事件

机器通过转换从一个状态移动到另一个状态。转换是由事件引起的;当事件发生时,机器转换到下一个状态。

在 Stately 的编辑器中,箭头表示转换,箭头线上的圆角矩形表示事件。每个转换都有一个状态,即转换之前的状态,以及一个目标状态,即转换之后的状态。转换的箭头从源状态开始,指向目标状态。

有几种不同类型的转换:

  • 普通转换由事件触发。
  • 受保护的转换由事件触发,但只有在满足指定条件时才会发生。
  • 延迟转换(也称为after转换)由事件触发,但只有在指定的时间间隔之后才会发生。
  • 无事件转换(也称为always转换)由计时器或其他条件触发,不需要事件。

创建转换和事件

  • 点击任意状态上的句柄以创建转换、事件和目标状态。
  • 从源状态的句柄拖动到目标状态的句柄以用转换和事件连接它们。

删除转换

删除状态也会删除以该状态为源的任何转换。

  • 使用 三点菜单或右键单击选定的转换,然后选择 删除 以删除选定的转换。
  • 使用 Backspace 键删除选定的转换。

更改转换源和目标

  • 使用 三点菜单或右键单击转换,然后选择 切换源和目标
  • 从一个状态拖动转换句柄到另一个状态。
  • 选择一个转换,从右侧工具菜单打开转换 详细信息 面板,然后从下拉菜单中选择新的源或目标状态。

延迟(after)转换

延迟转换 是在设定的时间之后才会发生的转换。如果在计时器结束前发生了另一个事件,转换不会完成。阅读更多关于延迟转换的信息。

在 Stately 的编辑器中,延迟转换标记为“after”。延迟转换的默认时间间隔为500毫秒(0.5秒)。

将转换变为延迟转换:

  • 使用 三点菜单或右键单击一个转换,然后从 事件类型 中选择 After
  • 选择一个事件,从右侧工具菜单打开转换 详细信息 面板,然后从 触发器 下拉菜单中选择 After

悬停时,延迟时间间隔将以人类可读的格式显示。例如,15000毫秒将显示为15秒。

设置延迟时间间隔:

  • 使用延迟转换上的文本输入框指定时间间隔(以毫秒为单位)。
  • 选择延迟转换,从右侧工具菜单打开转换 详细信息 面板,然后在 延迟 文本输入框中指定时间间隔(以毫秒为单位)。

将延迟转换变为普通转换,使用 三点菜单或右键单击一个转换,然后从 事件类型 中选择 事件

无事件(always)转换

无事件转换 是指在转换启用时 总是 发生的转换。在 Stately 的编辑器中,延迟转换被标记为“always”。阅读更多关于无事件转换的信息

将转换变为无事件转换的方法:

  • 使用 三点菜单或 右键单击 转换,然后从 事件类型 中选择 Always
  • 选择一个事件,打开右侧工具菜单中的转换 详细信息 面板,然后从 触发器 下拉菜单中选择 Always

将无事件转换变为常规转换的方法,使用 三点菜单或 右键单击 转换,然后从 事件类型 中选择 Event

状态完成事件

使用状态完成事件在其最终子状态到达时从父状态进行转换。阅读更多关于状态完成事件的信息

将事件变为状态完成事件的方法:

  • 使用 三点菜单或 右键单击 事件,然后从 事件类型 中选择 State Done event

将状态完成事件变为常规转换的方法,使用 三点菜单或 右键单击 转换,然后从 事件类型 中选择 Event

自转换

自转换 是指状态转换回自身,这对于更改上下文和/或执行操作而不更改有限状态非常有用。您还可以使用自转换重新启动状态。阅读更多关于自转换的信息

创建自转换的方法:

  • 使用 三点菜单或 右键单击 现有事件,然后选择 Make self transition。转换将连接回源状态。
  • 选择一个现有事件,打开右侧工具菜单中的转换 详细信息 面板,然后从源和目标下拉菜单中选择相同的状态。

添加守卫

守卫转换 是指只有在其条件评估为 true 时才启用的转换。阅读更多关于守卫转换的信息

在 Stately 的编辑器中,守卫按检查顺序编号,并标有“if”或“else if”以及其条件。多个守卫在同一事件上通过虚线连接。

添加守卫的方法:

  • 选择一个转换并使用 添加守卫 来为转换添加新的守卫。使用文本输入框添加守卫的条件。
  • 使用 三点菜单或 右键单击 转换并使用 添加守卫 为转换添加守卫。使用文本输入框添加守卫的条件。
  • 选择一个现有转换,打开右侧工具菜单中的转换 详细信息 面板,然后在 守卫 文本输入框中输入守卫的条件。

重新排序守卫的方法:

  • 使用 三点菜单或 右键单击 守卫转换,然后从 重新排序守卫 菜单中选择 上移下移

删除守卫的方法,从文本输入框中删除其条件。

您可以从 Sources 面板中为您的守卫添加实现代码。