Generator 本身不解决异步问题,而是提供暂停/恢复机制,需配合 next() 手动驱动或 Promise/thunk 封装实现自动执行;其 yield 可产出 Promise 或 Thunk,由外部处理异步并传回结果,错误需通过 it.throw() 注入,是 async/await 的前身。

Generator 可以把嵌套的回调函数“拉平”,让异步代码看起来像同步一样写,但需要配合 next() 手动驱动或用工具(比如 co 或 Promise 封装)来自动执行。它本身不解决异步问题,而是提供一种暂停/恢复的机制,关键在于如何把异步操作“塞进” yield 并交由外部处理。
理解 Generator 的暂停特性
Generator 函数返回一个迭代器对象,调用 next() 会执行到下一个 yield 暂停,并把 yield 后面的值作为 value 返回。这个“暂停点”就是插入异步逻辑的位置:
-
yield后可以放任何值(包括 Promise、thunk、甚至普通数据),但 Generator 不会自动等待它完成 - 真正实现“等待”,得靠外部代码拿到这个值后手动 resolve(比如调用
.then()),再用next(result)把结果传回去 - 所以 Generator 是“协程式”的协作调度,不是自动异步等待
用 Promise + 手动 next 实现简单封装
把每个 yield 出来的 Promise then 一下,成功后用 next(value) 继续,失败则 throw 进去:
function run(genFn) {
const it = genFn();
function next(val) {
const { value, done } = it.next(val);
if (done) return value;
return value.then(next).catch(err => it.throw(err));
}
return next();
}这样就能用:
立即学习“Java免费学习笔记(深入)”;
function* fetchUser() {
const res = yield fetch('/api/user');
const user = yield res.json();
console.log(user.name);
}
<p>run(fetchUser); // 自动执行,无需嵌套 .then配合 Thunk 简化(适合老项目过渡)
Thunk 是一个无参函数,内部执行异步并调用回调。Generator 配合 Thunk 时,yield 出的是这个函数,外部执行它并传入 callback(err, data),再用 next(data) 推进:
- Node.js 常见的
fs.readFile(path, cb)就是 Thunk 形式 - 可写个
thunkify工具把回调函数转成 Thunk - 比 Promise 少一层包装,但不如 Promise 流行,现在更推荐 Promise 方案
注意错误传递和流程控制
Generator 中 try/catch 只能捕获同步错误;异步错误要靠 it.throw() 注入,或者在封装层统一 catch 后触发 throw:
-
it.throw(err)会让 Generator 内部最近的catch捕获该错误 - 如果 Generator 内没
catch,错误会冒泡到封装函数的catch中 -
yield后不能直接await(ES2017+ 才支持async function*),别混用
Generator 是 async/await 的前身,现在多数场景直接用 async/await 更简洁。但如果要手写流程控制、做状态机、或兼容旧环境,Generator + Promise 封装仍是清晰可靠的方案。


















