概念介绍:从纯函数思想到副作用归一化

将窗口抽象想象为函数调用:如果能让所有窗口都表现为”纯函数”,就能解决同步问题

// 理想状态:窗口 = 纯函数
Window(userActions) => UIState

// 纯函数特性:相同输入 → 相同输出
Window(actions) === Window(actions) // 总是为 true

如果窗口表现为纯函数,用户输入行为对应存函数入参,传入相同入参执行后可以得到完全一致的页面输出,从而实现多个窗口效果同步。

然后,事实是副作用无处不在:

副作用产生的不确定性,导致相同入参调用还是会产生不同结果。

举例来说🌰:

const [uuid, setUuid] = useState();
<div onClick={handleTest}>button--{uuid}</div>

function handleTest() {
  const newUuid = getUuid();
  console.log(newUuid);
  setUuid(newUuid)
}

哪怕俩个窗口都触发调用 handleTest 方法,界面展示会因为 Uuid 的随机性出现差异化。

副作用归一化

什么是副作用归一化?

副作用归一化 = 让”不确定操作”变成”确定操作”

简单来说:由一个窗口先执行完整流程期间自动收集对应副作用结果,其他窗口执行相同操作副作用计算从记录中获取副作用结果,而不重新计算结果。

Leader窗口(发起):用户操作 → (执行副作用 → 收集结果 → 缓存)[劫持] → 同步
Other窗口(同步):用户操作 → (劫持副作用 → 从记录获取)[劫持] → 使用结果

副作用归一化难点: