co模块是Generator函数的自动执行器,通过递归调用next配合Promise驱动,统一处理Promise、数组、对象、thunk等yield值,并捕获异常实现错误兜底。

Generator 函数配合 co 模块,是 ES2017 引入 async/await 之前最接近其语义的异步流程控制方案。它并非“完美模拟”——因为底层机制不同(Generator 是协程暂停/恢复,async/await 基于 Promise 状态机),但确能以同步写法表达异步逻辑,且行为高度一致。
Generator + co 的核心工作原理
co 是一个自动执行器:它接收一个 Generator 函数,逐次调用 next(),当遇到 yield 后的 Promise(或 Thunk、数组、对象等可被 co 处理的值)时,会等待其 resolve/reject,并将结果传回 Generator;若 Promise 被 reject,co 会向 Generator 抛出错误,触发 try/catch 或被外层捕获。
这与 async/await 中 await 等待 Promise 完成、错误冒泡的行为逻辑完全对应。
基础用法:从 yield Promise 开始
确保你使用的是支持 Promise 的环境(Node.js ≥ 0.12 或浏览器支持 Promise)。安装 co:
npm install co
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
示例:用 yield 串行请求两个 API
const co = require('co');
const fetch = require('node-fetch'); // 或使用原生 fetch(浏览器)
<p>function getPost(id) {
return fetch(<code>https://jsonplaceholder.typicode.com/posts/${id}</code>)
.then(res => res.json());
}</p><p>function getUser(id) {
return fetch(<code>https://jsonplaceholder.typicode.com/users/${id}</code>)
.then(res => res.json());
}</p><p>// Generator 函数 —— 类似 async 函数
function* main() {
try {
const post = yield getPost(1); // 类似 await getPost(1)
const user = yield getUser(post.userId); // 类似 await getUser(...)
console.log(<code>${user.name} wrote: ${post.title}</code>);
} catch (err) {
console.error('Error:', err.message);
}
}</p><p>// co 执行它 —— 类似调用 async 函数并 .then()
co(main).then(() => console.log('done')).catch(console.error);
关键细节:co 支持的 yield 类型与错误处理
co 不仅支持单个 Promise,还能智能处理多种结构,让写法更灵活:
-
单个 Promise:直接
yield promise,返回 resolved 值 -
数组(并发):如
yield [fetch('/a'), fetch('/b')],等所有 Promise 完成后返回数组结果(类似Promise.all) -
普通对象(并发):如
yield { a: fetch('/a'), b: fetch('/b') },返回键值对对象(类似Promise.allSettled行为) -
嵌套 Generator:可
yield* anotherGenerator(),实现子流程复用 -
错误传播:任意
yield后的 Promise reject,都会中断执行并抛给外层try/catch或co(...).catch()
与 async/await 的差异及注意事项
虽然体验相似,但需注意几点本质区别:
-
函数类型不同:Generator 函数需用
function*声明,调用后返回迭代器,必须靠co或手动执行;async函数直接返回 Promise -
yield vs await:
yield可暂停任意表达式(包括非 Promise),而await强制转换为 Promise;若误yield一个普通值,co会立即继续,不报错但易掩盖逻辑问题 -
调试支持较弱:V8 和 DevTools 对
async/await的堆栈追踪、断点支持更完善;Generator 的暂停点在调试器中可能显示为next()调用而非原始yield行 -
已逐步淘汰:
co在 Node.js 8+ 和现代前端中已无必要;async/await是标准语法,更简洁、可靠、生态友好
因此,除非维护旧项目或教学演示,否则推荐直接使用 async/await。理解 Generator + co 是为了读懂历史代码、深入异步原理,而非新项目首选。

















