生成器通过yield主动让出执行权实现逻辑暂停,需手动调用.next()或调度器控制节奏;支持传参恢复和中途取消,但无法卸载cpu压力,耗时计算仍需配合web worker。

生成器本身不直接“暂停计算任务”,而是通过 主动让出执行权,把复杂计算拆成多个可中断的步骤,配合外部控制(比如手动调用 .next() 或调度器)来实现逻辑上的暂停。它不冻结线程、不阻塞主线程,也不干预 CPU 密集型运算本身——真正的暂停,靠的是把大任务切片 + yield 控制节奏。
把计算过程显式分步,用 yield 标记暂停点
不能指望生成器自动暂停一个 for 循环或递归;必须把原本连续的逻辑,改写成每次只做一小块、然后 yield 交出控制权。
- 比如遍历 100 万条数据做转换:不要写
for (let i = 0; i 一气呵成,而是每次处理 1000 条,yield 一次 - yield 后返回当前进度(如已处理数量、中间结果),方便 UI 更新或用户取消
- 示例:分块求和
let sum = 0;
for (let i = 0; i sum += arr[i];
if ((i + 1) % chunkSize === 0) {
yield { value: sum, progress: i + 1 }; // 暂停并汇报
}
}
return sum;
}
配合异步调度器,实现非阻塞式推进
如果想让浏览器保持响应,不能在单次 .next() 中做太多事。用 setTimeout、requestIdleCallback 或 Promise 微任务来“节流”调用:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 每次
.next()后,等一帧再继续,避免卡顿 - 用
requestIdleCallback在浏览器空闲时推进一步 - 简单调度示意:
let result = gen.next();
while (!result.done) {
await new Promise(r => setTimeout(r, 0)); // 下一微任务
result = gen.next();
}
return result.value;
}
支持中途取消和传参恢复
yield 不仅能输出,还能接收下一次 .next(value) 传入的数据——这让你可以在暂停时判断是否继续:
- 在 yield 处检查传入参数,比如
if (shouldStop) return; - 用户点击“暂停”按钮时,记录当前生成器对象;点“继续”时再调用
.next() - 甚至传入新参数动态调整后续行为(如修改 chunkSize)
注意:它不替代 Web Worker
生成器无法真正卸载 CPU 压力。如果计算本身极其耗时(如加密、图像处理),单靠 yield 分片仍会阻塞主线程。这时应结合 Web Worker 把重计算移出主线程,生成器只负责协调与通信。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










