生成器适合做任务切片,因其函数天然支持yield暂停与next恢复,精准匹配“执行一点→让出→空闲→再执行”逻辑,比setTimeout/Promise更易控节奏,比Web Worker更轻量。

用生成器模拟时间切片,核心是把一个耗时循环拆成多次暂停执行,每次只干一小段,主动让出主线程,给浏览器留出响应用户操作、渲染帧的时间。
为什么生成器适合做任务切片
生成器函数(function*)天然支持暂停与恢复:yield 会交出执行权,下次调用 next() 才继续。这正好匹配“执行一点 → 让出 → 等待空闲 → 再执行一点”的切片逻辑。它比单纯用 setTimeout 或 Promise.then 更易控制流程节奏,也比 Web Worker 更轻量——无需跨线程通信,所有状态保留在当前作用域。
基础切片执行器写法
封装一个通用的切片驱动函数,接收生成器并自动调度:
- 每次调用 gen.next() 执行一段逻辑,检查是否完成(done === true)
- 未完成时,用 requestIdleCallback 延迟到浏览器空闲时再执行下一段(更精准);或退而求其次用 setTimeout(..., 0)(兼容性更好)
- 避免单次执行超 50ms,可在循环中加计时判断,到时间就 yield 中断
示例片段:
function timeSlicing(genFn, ...args) {
const gen = genFn(...args);
function next() {
const start = performance.now();
let res;
do {
res = gen.next();
if (res.done) return;
} while (performance.now() - start 实际场景:批量渲染 30 万条数据
比如要往页面追加 30 万个 这样用户仍可滚动、输入、点击,页面不冻结,只是数据“渐进式”出现。 生成器切片不是银弹,要注意几点:
注意事项和边界情况











