JavaScript生成器是可暂停恢复的特殊函数,通过yield实现状态保持,为async/await提供思想基础;虽不直接处理异步,但支撑协程模式及Redux-Saga等应用。

JavaScript生成器(Generator)是一种特殊函数,能暂停和恢复执行,配合 yield 关键字实现“可中断的函数”。它本身不直接处理异步,但为手动或库级异步流程控制提供了底层机制——真正简化异步的是基于生成器的协程模式(如 co 库)或后续演进的 async/await。
生成器的核心:函数可暂停、状态可保持
普通函数一旦开始执行,就会一直运行到结束或遇到 return;而生成器函数用 function* 声明,调用后返回一个迭代器对象,不立即执行。每次调用迭代器的 next() 方法,函数才从上次暂停处继续,直到下一个 yield 或结束。
这意味着:局部变量、执行位置、调用栈状态都会在 yield 时被保留,下次恢复时原样接续——这是实现“类同步写法”的关键基础。
用生成器模拟异步串行:手动驱动 + 回调
虽然不推荐在现代代码中手动这么做,但理解其原理有助于看清价值:
立即学习“Java免费学习笔记(深入)”;
- 把异步操作(如
fetch)包装成接受回调的函数,并在yield后传入结果 - 用一个“执行器”(runner)反复调用
next(),并在回调触发后把数据传回生成器 - 生成器内部就像写同步代码一样,用
const data = yield asyncCall()获取结果
例如:
// 简化示意,省略错误处理
function* fetchFlow() {
const user = yield fetch('/api/user');
const posts = yield fetch(`/api/posts?uid=${user.id}`);
return { user, posts };
}这个结构清晰表达了依赖关系,无需嵌套回调或手动链式
then。
生成器是 async/await 的思想前身
async/await 在语法和语义上高度借鉴了生成器协程的设计:
-
async函数本质是语法糖,底层仍依赖 Promise 和状态机 -
await类似yield,暂停执行并等待 Promise settle,再恢复 - 两者都让异步逻辑线性展开,避免“回调地狱”,提升可读性和可调试性
区别在于:async/await 原生支持、自动处理 Promise、无需额外执行器,而生成器需要手动或借助库(如 co)才能达到类似效果。
实际开发中:优先用 async/await,理解生成器助你深入原理
生成器在现代前端已较少直接用于异步控制,但它仍在以下场景有价值:
- 实现自定义迭代逻辑(如遍历树、生成无限序列)
- 与 Redux-Saga 配合做副作用管理(saga 就是基于生成器的中间件)
- 学习 JavaScript 运行时机制、协程模型和异步演进脉络
掌握生成器,不是为了写更多 yield,而是看清 JavaScript 是如何一步步让异步变得像同步一样自然的。










