Generator 通过暂停/恢复执行配合运行器实现异步流程控制,核心是 yield 返回 Promise 后由运行器等待其 resolve 再调用 next();手写简易运行器仅需十几行,但需注意 yield 值类型及 try/catch 错误处理;async/await 是其语法糖,现代开发应优先使用。

Generator 本身不直接处理异步,但它通过 暂停/恢复执行 的能力,配合外部运行器(如 co 或手动调用 next()),可以把异步操作“伪装”成同步写法——核心是让函数在 yield 处暂停,等异步结果回来再继续。
Generator 配合 Promise 实现自动流程控制
最常用方式是用一个运行器函数接管 Generator 执行:每次 yield 出一个 Promise,运行器等它 resolve 后,把结果传回 next() 继续执行。
- Generator 内部用
yield fetch('/api/user')这样的语句,看起来像同步获取数据 - 运行器捕获这个 Promise,
.then(data => gen.next(data))触发下一步 - 如果
yield出的是普通值,直接gen.next(value);如果是 Promise,就等它完成再调
手写一个简易 co 类运行器
不需要第三方库,十几行就能实现基础功能:
function run(genFn) {
const gen = genFn();
function next(data) {
const { value, done } = gen.next(data);
if (done) return value;
if (value instanceof Promise) {
return value.then(next);
}
return next(value);
}
return next();
}这样就可以写:
立即学习“Java免费学习笔记(深入)”;
run(function* () {
const res = yield fetch('/api/user');
const json = yield res.json();
console.log(json);
});注意 yield 后的值类型和错误处理
yield 后推荐只放 Promise(或 thenable 对象),否则运行器无法统一等待。错误要用 try/catch 包裹,因为 Promise 拒绝会触发 Generator 的 throw() 方法:
- 在 Generator 内
try { yield fetch(...) } catch(e) { ... }可捕获网络错误 - 运行器需在
.catch()中调用gen.throw(err),把错误送进 Generator - 没加
catch会导致整个流程中断,类似未捕获的 Promise rejection
对比 async/await:Generator 是 async/await 的底层基础
ES2017 的 async/await 本质上就是语法糖,编译后行为与 Generator + 自动运行器高度相似:
-
async function编译为 Generator 函数 + 自动运行逻辑 -
await等价于yield+ 运行器等待 Promise - 现代开发优先用
async/await——更简洁、原生支持、调试友好


















