ES6生成器函数详解
ES6引入的生成器函数(Generator Function)是一种特殊的函数,允许通过yield关键字暂停和恢复执行流程。生成器函数在定义时使用function*语法,调用时返回一个生成器对象(Generator Object),而非直接执行函数体。
生成器对象遵循迭代器协议(Iterator Protocol),可通过next()方法逐步执行代码,每次遇到yield时暂停,并返回一个包含value和done属性的对象。value为yield后的表达式值,done表示生成器是否执行完毕。
语法特性
- 定义方式 
 使用- function*声明生成器函数:- function* generatorFunc() {yield 1;yield 2;return 3; }
- yield关键字- yield用于暂停函数执行并返回一个值,后续调用- next()时从暂停处继续执行。
- 迭代器协议 
 生成器函数返回的迭代器对象符合迭代器协议,包含- next()、- return()和- throw()方法。
- yield*委托
 用于委托给另一个生成器或可迭代对象:- function* generatorA() {yield 1; } function* generatorB() {yield* generatorA(); }
应用场景
- 惰性求值生成器适合处理大数据集或无限序列,仅在需要时计算值。例如生成斐波那契数列: - function* fibonacci() {let [a, b] = [0, 1];while (true) {yield a;[a, b] = [b, a + b];} } const fib = fibonacci(); console.log(fib.next().value); // 0 console.log(fib.next().value); // 1
- 异步流程控制生成器可用于简化异步代码,结合 - yield暂停特性,实现类似同步的异步操作写法。例如:- function* fetchUser() {const response = yield fetch('https://api.example.com/user');const data = yield response.json();return data; } const generator = fetchUser(); const promise = generator.next().value; promise.then(response => {return generator.next(response).value; }).then(data => {console.log(generator.next(data).value); });
- 状态机 
 生成器天然适合实现状态机逻辑,每个- yield代表一个状态节点:- function* trafficLight() {while (true) {yield 'red';yield 'yellow';yield 'green';} } const light = trafficLight(); light.next().value; // 'red' light.next().value; // 'yellow'
注意事项
- 执行顺序:生成器函数在首次调用next()时才开始执行,而非声明时。
- 错误处理:可通过generator.throw()向生成器内部抛出错误,需在函数体内用try/catch捕获。
- 资源清理:若提前终止生成器,应调用generator.return()释放资源。
- 兼容性:旧版浏览器需通过Babel等工具转译。
优化建议
- 避免频繁创建:对性能敏感场景,复用生成器对象而非重复创建。
- 结合for...of:遍历生成器时使用for...of语法更简洁:for (const value of fibonacci()) {if (value > 100) break;console.log(value); }
- 与Promise配合:使用库如co或异步生成器(ES2018)进一步简化异步代码:async function* asyncGenerator() {yield await Promise.resolve(1); }
总结
生成器函数提供了一种控制执行流程的灵活机制,适用于异步编程、惰性计算和状态管理等场景。尽管现代JavaScript已引入async/await处理异步操作,生成器仍在特定场景下具有独特优势。合理使用生成器能提升代码可读性和维护性,但需注意其执行特性和性能开销。