generator本身不是异步执行的,但可通过yield暂停、promise包装和外部runner驱动实现类似async/await的效果;需手动调度next()、处理promise resolve/reject,且存在调试难、无隐式promise、不支持任意函数yield等限制。

Generator 本身不是异步执行的,但它能配合 Promise 和手动调度(比如 next() 调用)模拟 async/await 的写法。核心思路是:用 yield 暂停执行,把异步操作包装成 Promise,再由外部运行器(runner)接管控制流,等 Promise 完成后自动调用 next(value) 继续。
Generator + Promise 构建类 async 函数
关键在于把 yield 后的值当作待 resolve 的 Promise 处理。例如:
普通 Generator:
function* fetchUser() {
const user = yield fetch('/api/user'); // 这里 yield 出一个 Promise
console.log(user);
}
但直接调用不会自动等待 Promise,需要一个 runner 来驱动它:
function run(genFn) {
const gen = genFn();
function next(data) {
const { value, done } = gen.next(data);
if (done) return value;
return Promise.resolve(value).then(next);
}
return next();
}
这样调用 run(fetchUser) 就能顺序等待 fetch 结果。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
支持 await-like 的多层 yield 和错误处理
真实场景中要处理 reject、嵌套 Promise、甚至多次 yield。改进 runner:
- 用
try/catch捕获 Promise rejection,并调用gen.throw(err) - 对非 Promise 值直接
next(value),避免Promise.resolve()开销 - 支持同步值(如
yield 42)和异步值(yield Promise.resolve(42))统一处理
对比 async/await 的差异与限制
Generator 实现的“类 async”只是语法近似,本质不同:
- 必须显式调用 runner,不能像
async函数那样直接await - 无法在任意函数中
yield,只能在 generator function 内部使用 - 没有隐式 Promise 包装:
async函数返回值自动转为 Promise,Generator 必须靠 runner 返回 Promise - 调试更复杂,堆栈不连续,Chrome DevTools 对 generator 的单步支持不如 async/await 直观
现代替代方案:优先用 async/await
ES2017 起,async/await 已成为标准且更简洁可靠的异步方案。Generator 方案主要用于:
- 学习 JS 异步机制底层原理
- 兼容极老环境(需 Babel + regenerator-runtime)
- 构建自定义控制流(如状态机、协程式游戏逻辑)
实际项目中,除非有特殊需求,不建议用 Generator 手动实现 async 语义——既增加维护成本,又失去语言原生优化优势。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










