generator 本身不直接管理状态,但可配合 redux、zustand 等库构建支持时间旅行的动作流程:将用户操作封装为可中断/重放的 generator 函数,由调度器记录执行上下文与状态快照,实现 undo/redo。

Generator 本身不直接管理状态,但它能为动作序列提供可控的暂停/恢复能力,配合状态管理库(如 Redux、Zustand 或自研轻量方案),可构建带时间旅行(time-travel)能力的动作分发流程。核心思路是:把每个“用户操作”封装为一个可中断、可重放的 Generator 函数,并用一个中央调度器记录执行上下文与快照。
用 Generator 封装原子动作并捕获中间状态
每个动作不再是普通函数,而是返回 Iterator 的 Generator。它可在关键节点 yield 当前 state 或副作用结果,便于回溯时复原执行路径。
例如:
function* incrementAsync() {
yield { type: 'INCREMENT_START' };
yield delay(200);
yield { type: 'INCREMENT_SUCCESS', payload: 1 };
}每次 next() 调用推进一步,调度器可保存每步产出的 action 和当前 state 快照。
构建可回溯的调度器(Reversible Executor)
调度器需维护:
- 动作生成器实例(iterator)
- 历史快照栈(state + iterator position)
- 当前执行指针(指向哪一步)
关键操作包括:
- dispatch(action):若 action 是 Generator,创建 iterator 并执行首步,存快照
-
undo():弹出上一个快照,重置 state,并将 iterator 回退到前一位置(需手动模拟“反向 next”,通常靠保存
iterator的克隆或执行日志) - redo():重放被 undo 跳过的那几步(依赖已缓存的 yield 值或重执行 generator)
注意:原生 Generator 不支持倒退,所以实际中常用“快照+重放”而非真·反向迭代。
与 Redux 集成:用中间件桥接 Generator 动作
写一个 Redux 中间件,识别 Generator action:
const generatorMiddleware = store => next => action => {
if (typeof action[Symbol.iterator] === 'function') {
const iterator = action[Symbol.iterator]();
const runStep = () => {
const { value, done } = iterator.next();
if (!done && value) store.dispatch(value);
if (!done) setTimeout(runStep, 0); // 异步推进
};
runStep();
return;
}
return next(action);
};再配合 Redux DevTools 的 liftedStore,就能在 UI 上点击任意历史 state,重放从初始到该点的所有 Generator 步骤。
Zustand / 自研方案更轻量:用 create 切片 + 手动快照
无需中间件,直接在 store 方法中调用 Generator 并管理历史:
create((set, get) => ({
count: 0,
history: [],
dispatchGen: (genFn) => {
const gen = genFn();
const steps = [];
let result = gen.next();
while (!result.done) {
steps.push(result.value);
result = gen.next();
}
// 每步都触发 set 并存快照
steps.forEach(step => {
set(prev => {
const newState = reducer(prev, step);
get().history.push({ state: {...newState}, step });
return newState;
});
});
}
}));这样每步都可精确还原,且不依赖外部工具链。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











