generator 本身不执行异步操作,仅通过 yield 暂停/恢复执行;需配合 promise 和执行器(如 co)或 async/await 才能实现真正的异步流控制。

Generator 配合 yield 本身不直接执行异步操作,但它能以同步写法暂停/恢复函数执行,为手动或自动调度异步任务提供结构基础。真正的“异步流”需要配合 Promise、执行器(如 co)或现代 async/await 思路来驱动。
Generator 是暂停器,不是执行器
调用 Generator 函数返回一个迭代器对象,每次调用 .next() 才走到下一个 yield 并暂停。yield 后的值只是被产出,不会自动等待或解析 Promise:
function* fetchFlow() {
const res = yield fetch('/api/data'); // fetch 被立即调用,返回 Promise
console.log(res); // 但这里 res 是 Promise 对象,不是响应体
}
const it = fetchFlow();
console.log(it.next()); // { value: Promise, done: false }
所以关键在于:如何让 yield Promise 真正“等它 resolve 后再继续”?
手动驱动:用 .next() 传入 resolve 结果
你可以自己监听 Promise,然后把结果传给下一次 .next():
function* apiFlow() {
const user = yield fetch('/user');
const posts = yield fetch(`/posts?uid=${user.id}`);
return [user, posts];
}
<p>const it = apiFlow();
it.next().value.then(userRes =>
userRes.json().then(userData =>
it.next(userData).value.then(postRes =>
postRes.json().then(postData =>
it.next(postData).value // 最终返回 [userData, postData]
)
)
)
);</p>这种方式逻辑清晰但嵌套深,实际中一般交给执行器处理。
用 co 或自定义 runner 自动处理 Promise
经典库 co 就是为这而生:它接收 Generator 函数,自动调用 .next(),并当遇到 Promise 时 await 它,再把结果传回:
- yield 普通值 → 直接传入 next()
- yield Promise → 等待 resolve,再把结果传入 next()
- yield 数组或对象 → 并发执行所有 Promise(类似
Promise.all)
const co = require('co');
<p>co(function* () {
const user = yield fetch('/user').then(r => r.json());
const posts = yield fetch(<code>/posts?uid=${user.id}</code>).then(r => r.json());
console.log(user, posts); // ✅ 顺序执行,无嵌套
});</p>现代替代:async/await 已覆盖大部分场景
ES2017+ 的 async/await 本质是语法糖,底层也依赖 Promise 和状态机,比手写 Generator + runner 更简洁直观:
async function apiFlow() {
const user = await fetch('/user').then(r => r.json());
const posts = await fetch(`/posts?uid=${user.id}`).then(r => r.json());
return [user, posts];
}
Generator + yield 异步流的价值现在更多体现在:
- 需要精细控制执行节奏(如分页拉取、限流迭代)
- 构建可中断/可恢复的数据流(配合
for await...of+ 可迭代 Promise) - 学习 JS 运行时机制和协程思想
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











