Day27 - 子状态 or 子状态机?与外部沟通!概念简介: invoke services v.s. spawn actors in XState

先前我们介绍过了阶层式状态,让我们能将一个状态向下描述得更精确,比如以之前的 input 元件状态机
当 input 是 changed 时,可以更向下描述,这个 changed 是 valid 或 invalid 的。

或者我们说 valid 、 invalid 唯有存在 changed 底下才是有意义的。
https://ithelp.ithome.com.tw/upload/images/20210929/20130721UvlbWhoZpj.png

情境简介

然而现实的复杂情境中,阶层状态或许也会不堪使用,比如我想要制作一个 TODO List APP ,这个 List 我想拥有 loading / ready 的状态...而 List 底下可有许多 TODO Item (0 - N)个,这个数量会随使用者输入而改变!

每个 TODO Item 可以有状态:编辑中(editing)、预览中(reading)、删除(deleted);资料(延伸状态):标题(title)、完成状态(completed)
https://ithelp.ithome.com.tw/upload/images/20211012/20130721dhWtA85slL.png

如果我们将 TODO Item 视为 TODO LIST 的子状态,我们要如何一开始就知道要写几组 todo 进入 machine config?而且每个 TODO Item 又有各自的状态跟资料...

我们可以将 TODO Item 视为 TODO LIST 的子状态机,然而这个 子状态机 TODO Item 又必须要与 父状态机 TODO LIST 进行状态沟通及资料传递,比如说我按下全部完成,要让所有的 TODO Item 被设定为已完成、按下删除,要让 TODO LIST 移除一个子状态机 TODO Item 。

这里采用的子状态机是指能储存状态的 Serive,父子状态机彼此的通讯及资料传递,也就是「Service」与「Service」间的讯息传递、互动。

这一类型「Service」的互动或者我们可以称为「Actor」,已经有相当出名的理论支持!Actor Model:一种能保存内部状态、与外部沟通,并且能建立其他 Service 的数学运算模型。

XState 提供两种方式让我们建立子状态机

  1. Invoke(唤起、调用)
  2. Spawn(繁殖、生产)

两者差别是 子状态机 能不能在 父状态机 的状态之间共享;也就是 这个子状态机 是活在某个特定状态下之下 or 所有状态下!

以底下 stackoveflow 的程序码为 example

Invoke

这个被 invoke 的 child machine 就只存活在「pending」状态里,一离开「pending」child machine 就会结束服务。

// Machine 是 XState 旧版 API
const parentMachine = Machine({
  id: 'parent',
  initial: 'pending',
  states: {
    pending: {
      invoke: {
        src: childMachine
      }
    }
  }
});

Spawn

这个被 spawn 的 child machine 存活在所有的状态里,你看虽然范例命名不太好,它存放在 context 叫做 localOne ,但在其他的 state 都可以透过 context 拿到拿到这台名为 localOne 的 child machine 。

// Machine 是 XState 旧版 API
const parentMachine = Machine({
  id: 'parent',
  initial: 'waiting',
  context: {
    localOne: null
  },
  states: {
    waiting: {
      entry: assign({
        localOne: () => spawn(childMachine)
      })
    }
  }
});

建立子状态机之外

Invoke 和 Spawn 也可以让我们的状态机与外部沟通,比如说我想等一个 promise 回来的资料或是某个 state 时我想执行某个 callback ,或者在某个状态下,我想要建立 Observable 让内外持续沟通。

参考资料


<<:  [Day27] Dev Ops

>>:  程序语言篇

总结与心得

经过漫长的环境设定与软件安装後 终於把 SQL Server Failover Cluster 基本...

课堂小考 - 深度学习 Deep Learning Q&A(1)

Introduction to Machine Learning Ture and False D...

【D18】调整一下步伐,看看现在学到什麽

前言 进度已经超过一半,发现架构有点混乱,所以现在先整理一下,学会到什麽,以及怎麽运用,未来会怎样前...

番外篇 - NestJs - Guard

NestJs - Guard 验证分为两种,登入权限验证以及角色验证 举例说明:我们将 API 分为...

Day6 Class vs Function

前言 今天我打算说一下class跟function的差别,由於function component新...