当前位置: 首页 > news >正文

生成器函数概念与用法详解

生成器函数(Generator Function)是 JavaScript 中一种特殊的函数,它允许你逐步执行函数体,并在过程中多次返回(或“产出”)值,而不是一次性执行完毕。这种特性使得它非常适合处理异步操作、创建迭代器和处理大数据集等场景。


核心概念

  1. 语法标记
    使用 function* 声明(注意星号 * 的位置):
function* myGenerator() {// 函数体
}
  1. yield 关键字
    在函数内部用 yield 暂停执行并返回一个值:
function* numberGenerator() {yield 1;yield 2;yield 3;
}
  1. 返回生成器对象
    调用生成器函数时,不会立即执行函数体,而是返回一个生成器对象(Generator Object)。该对象符合迭代协议,可通过 .next() 方法逐步执行:
const gen = numberGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

关键特性

特性说明
惰性执行每次调用 .next() 才执行到下一个 yield,节省内存
双向通信可通过 .next(value) 向生成器内部传递值(作为 yield 的返回值)
错误处理用 .throw(error) 向生成器内部抛出错误,可在函数内用 try…catch 捕获
提前终止用 .return() 强制结束生成器

常见用途

  1. 创建自定义迭代器
function* range(start, end) {for (let i = start; i <= end; i++) {yield i;}
}for (const num of range(1, 5)) {console.log(num); // 依次输出 1, 2, 3, 4, 5
}
  1. 简化异步流程(类似 async/await)
function* fetchUser() {const user = yield fetch('/api/user'); // 暂停等待异步操作const posts = yield fetch(`/api/posts?userId=${user.id}`);return posts;
}// 手动执行(实际可用 co 等库自动处理)
const gen = fetchUser();
gen.next().value.then(user => gen.next(user).value).then(posts => console.log(posts));
  1. 无限数据流
function* infiniteSequence() {let i = 0;while (true) {yield i++;}
}const gen = infiniteSequence();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
// ...可无限调用
  1. 状态机实现
function* trafficLight() {while (true) {yield '🟢'; // 绿灯yield '🟡'; // 黄灯yield '🔴'; // 红灯}
}const light = trafficLight();
light.next().value; // 🟢
light.next().value; // 🟡

与普通函数的区别

特性普通函数生成器函数
执行方式一次性执行到底可暂停/恢复
返回值单一值(或 undefined)返回生成器对象(可迭代)
关键字returnyield(多次返回)
内存占用一次性分配所有资源按需生成值,节省内存

浏览器兼容性

  • 现代浏览器和 Node.js 均支持(ES2015+ 标准)
  • 旧环境需通过 Babel 等工具转译

生成器函数为 JavaScript 提供了更灵活的流程控制能力,是处理异步迭代、大型数据流和复杂状态逻辑的强大工具。

http://www.lqws.cn/news/476029.html

相关文章:

  • 【Clickhouse系列】增删改查:对比mysql
  • Clickhouse官方文档学习笔记
  • FastAPI 入门教程 #06:FastAPI 请求体和数据模型
  • 从零理解鱼眼相机的标定与矫正(含 OpenCV 代码与原理讲解)
  • PostgreSQL全栈部署指南:从零构建企业级高可用数据库集群
  • React Next快速搭建前后端全栈项目并部署至Vercel
  • 《DeepSeek原生应用与智能体开发实践》案例重现
  • 关于数学函数和数据类型扩展的详细讲解(从属GESP二级)
  • 30天pytorch从入门到熟练(day1)
  • Mybatis-Plus支持多种数据库
  • 【机器学习四大核心任务类型详解】分类、回归、聚类、降维智能决策指南
  • 多项目预算如何集中管控与动态调整
  • 将Linux装进口袋: Ubuntu to Go 制作
  • 【Linux】进程间多种通信方式对比
  • Typescript基础
  • 【后端】负载均衡
  • MiniMax-M1 开源,Kimi 深度研究内测,GPT-5 今夏发布,Gemini 2.5 稳定上线!| AI Weekly 6.16-22
  • 大模型MetaGPT面试题汇总及参考答案
  • Python-break、continue与else语句
  • OJ搭建:Judge0服务器、DeepSeek服务接入简介
  • 70、爬楼梯
  • 相机camera开发之差异对比核查四:测试机和对比机的Camera动态参数差异对比及关键字
  • 笨方法学python-习题1
  • 设计模式精讲 Day 10:外观模式(Facade Pattern)
  • 无锡哲讯科技:助力纺织业搭乘 SAP 数字化快车
  • [xiaozhi-esp32] 应用层(9种state) | 音频编解码层 | 双循环架构
  • OpenGL ES 中的材质
  • 《高等数学》(同济大学·第7版)第五章 定积分 第二节微积分基本公式
  • ASP.NET Core API文档与测试实战指南
  • 创建 Vue 3.0 项目的两种方法对比:npm init vue@latest vs npm init vite@latest