ES6迭代器和生成器底层是同步暂停-恢复机制,依赖迭代协议(next()返回{value,done}),生成器函数返回可逐步推进的状态机;异步控制需外部调度器驱动yield出的Promise并调用next()恢复执行。

ES6 迭代器和生成器本身不处理异步,它们的底层原理是同步的暂停-恢复机制 + 迭代协议,异步控制流靠的是外部调度器(比如手动 runner 或 co 库)把 yield 出来的 Promise “接住”并驱动其完成后再调用 next() 恢复执行。
迭代器协议是基础:next() 返回 {value, done}
任何对象只要实现 next() 方法,并返回形如 { value: ..., done: true/false } 的对象,就符合迭代器协议。数组、Set、Map 等原生结构都内置了这个协议。生成器函数返回的正是这样一个对象——它不是普通函数调用结果,而是一个“可逐步推进的状态机”。每一次 next() 调用,都在推动这个状态机向前走一步,直到 done: true。
生成器函数是语法糖:function* + yield = 可中断的执行上下文
生成器函数执行时不会一气呵成,而是:
- 调用
gen()仅创建迭代器,不运行函数体 - 首次
next()启动执行,运行到第一个yield就暂停,保存全部局部变量、执行位置、作用域链 - 后续
next()从暂停处继续,直到下一个yield或return
这种“保留执行上下文”的能力,让生成器天然适合作为异步流程的“骨架”——它不关心 value 是数字还是 Promise,只负责交出控制权,等外部决定何时恢复。
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
异步控制的关键不在 yield,而在谁调用 next() 和何时调用
yield 本身只是暂停并返回值;真正串联异步的是外部逻辑。常见模式是:
- 生成器
yield fetch('/api')→ 返回一个 Promise - runner 拿到该 Promise,用
.then(res => gen.next(res))在 resolve 后恢复生成器 - 如果 yield 的是多个 Promise,runner 可递归处理,形成自动“等待链”
也就是说,生成器提供暂停点,Promise 提供异步结果,runner 承担调度责任——三者协作才构成完整的异步控制流。这也是为什么现代开发直接用 async/await:它把 runner 内置进语言层,省去了手写调度的麻烦。
和 async/await 的关系:后者是前者的语法封装
async/await 并非另起炉灶,它的执行模型与生成器高度一致:
- 遇到
await就暂停,保存上下文 - Promise settle 后自动恢复后续代码
- V8 引擎内部确实曾基于生成器实现早期
async支持
区别在于:async 函数返回 Promise,天生融入事件循环;生成器返回迭代器,需要额外胶水代码。所以生成器的“底层原理”其实是 JavaScript 协程思想的原始落地形式,是理解现代异步语法演进的重要一环。

















