generator 通过 yield 暂停执行并配合 promise 手动驱动,可实现串行异步请求;需注意 fetch 返回 response 而非 json,须显式调用 .json() 并检查 res.ok。

Generator 本身不直接处理异步,但它能用 yield 暂停执行、交出控制权,配合 Promise 和手动驱动(或封装成自动执行器),就能把多步 Fetch 请求写得像同步代码一样清晰——关键在于“暂停等待响应,再继续下一步”。
Generator + Promise 手动驱动:最简可控方式
Generator 函数返回迭代器,每次调用 next() 得到一个 {value, done} 对象。如果 value 是 Promise,就等它 resolve 后再调用下一次 next():
- 定义 Generator,每步
yield fetch(...),返回 Promise - 写个递归函数,接收迭代器,
next()→ 拿到 Promise →.then()里再调自己 - 这样每步 Fetch 完才走下一步,无竞态、易调试
示例片段:
function* dataFlow() {
const user = yield fetch('/api/user');
const posts = yield fetch(`/api/posts?uid=${(await user).id}`);
const comments = yield fetch(`/api/comments?pid=${(await posts).data[0].id}`);
return { user: await user, posts: await posts, comments: await comments };
}
<p>function run(gen) {
const it = gen();
function next(val) {
const { value, done } = it.next(val);
if (done) return value;
return value.then(next);
}
return next();
}</p>用 co 或自建 runner 简化流程
手写递归容易出错,可用成熟库如 co(早期用于 Generator 异步),或仿照它写轻量 runner:
-
co会自动识别yield后的 Promise、Array、Object,并并发/串行处理 - 现代更推荐用
async/await,但 Generator 在需中途暂停、重试、取消或与 Redux-Saga 等中间件集成时仍有价值 - 若只串行 Fetch,runner 只需支持 Promise 即可,几行就能搞定
配合状态管理做分步加载 UI
Generator 的暂停特性天然适合控制 UI 状态:每 yield 代表一个加载阶段,可实时更新 loading 提示或骨架屏:
- 在
next()前设置当前步骤状态(如loadingStep = 'user') - Promise resolve 后再进下一步,同时更新数据和 UI
- 出错时可在 Generator 内
try/catch,统一处理错误并中断流程
注意点:Fetch 返回的是 Response,不是 JSON
别忘了 yield fetch(url) 得到的是 Response 对象,必须显式调用 .json() 或 .text() 才能读取内容:
- 常见写法:
const res = yield fetch('/api/data'); const data = yield res.json(); - 也可封装工具函数:
yield json(fetch('/api/data')),让 Generator 更干净 - 网络错误、4xx/5xx 需检查
res.ok,否则.json()会抛异常
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











