generator 通过 yield 实现帧粒度的异步逻辑暂停与恢复,配合 requestanimationframe 驱动,以同步风格编写可中断动画;需手动管理并发、中断及帧节奏,本质是协作式迭代器而非自动协程运行时。

在游戏逻辑中,Generator 不是直接驱动帧循环的“协程运行时”,但它能以极简方式组织异步、分帧的逻辑——核心在于把每帧要做的工作封装成可暂停/恢复的生成器函数,再由主循环(如 requestAnimationFrame)逐次调用 .next()。
用 Generator 拆解动画为“帧粒度”的可中断步骤
传统动画常靠嵌套 `setTimeout` 或状态机管理阶段,容易耦合、难调试。Generator 让你像写同步代码一样描述分帧过程:
- 每个 yield 表示“这一帧结束,等下一帧再继续”
- yield null 是最轻量的挂起;也可 yield 数字表示“跳过几帧”,或 yield Promise 实现资源加载等待
- 生成器函数返回的是迭代器,它持有完整执行上下文(局部变量、执行位置),天然支持状态保持
配合 requestAnimationFrame 构建驱动器
主循环不关心具体逻辑,只负责推进所有活跃的生成器:
const animations = new Set();
<p>function runAnimation(gen) {
const iterator = gen();
animations.add(iterator);</p><p>function tick() {
for (const it of Array.from(animations)) {
const { done } = it.next();
if (done) animations.delete(it);
}
requestAnimationFrame(tick);
}</p><p>if (animations.size === 1) requestAnimationFrame(tick); // 启动
}</p><p>// 示例:2 秒淡入(60fps ≈ 120 帧)
function* fadeIn(el) {
el.style.opacity = 0;
for (let i = 0; i </p><p>runAnimation(() => fadeIn(document.getElementById('hero')));
</p>
处理并发、中断与生命周期
真实游戏中需控制多个动画并行、提前终止、响应事件:
-
中断:迭代器无原生 cancel,但可约定 yield 返回值为
{ done: true }或检查外部 flag(如if (el.dataset.aborted) return) - 并发:每个生成器独立运行,互不阻塞;用 Set 或 Map 管理多个 iterator 实例即可
-
帧节奏控制:yield 数字时,在驱动器中读取
result.value,跳过对应帧数;yield Promise 时用await+ `async` 驱动器(需搭配 async generator)
注意边界:Generator ≠ 运行时协程
JavaScript 的 Generator 是协作式、非抢占式的,它不会自动调度或并发执行。它只是提供暂停/恢复能力,真正的“逐帧”依赖外部循环推动。不要试图在生成器里写长循环(如 while(true) 不 yield),否则会卡死主线程。真正复杂的状态流(如 AI 行为树、技能连招)建议结合有限状态机(FSM)+ Generator 封装各状态内的帧逻辑,兼顾清晰性与可控性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











