2021-03-20 03:10:34
JS的生成器函数是一种特殊函数,通过function*定义,可暂停执行并返回迭代器对象,支持多次返回值,适用于异步编程、自定义迭代器等场景。
核心特性
暂停与恢复:生成器函数通过yield关键字暂停执行,保留上下文,后续通过迭代器的next()方法恢复执行。
返回迭代器对象:调用生成器函数时不会立即执行,而是返回一个迭代器对象,该对象控制函数执行流程。
逐次返回值:每次调用next()返回一个对象,包含value(稿唤当前yield的值)和done(是否执行完毕)属性。
定义与使用
语法:使用function*定义生成器函数,内部通过yield指定暂停点。
示例:function* myGenerator() { yield 1; yield 2; yield 3;}const iterator = myGenerator();console.log(iterator.next()); // { value: 1, done: false }console.log(iterator.next()); // { value: 2, done: false }console.log(iterator.next()); // { value: 3, done: false }console.log(iterator.next()); // { value: undefined, done: true }
异步编程应用
简化流程控制:生成器函数可按顺序执行异步任务,避免回调地狱。
示例:通过递归调用next()实现异步任务队列:function* asyncTaskQueue(tasks) { for (const task of tasks) { const result = yield task(); // 假设task返回Promise console.log('Task completed:', result); }}function runTask(iterator, value) { const result = iterator.next(value); if (!result.done) { result.value.then(res => runTask(iterator, res)); }}
与迭代器的关系
自动实现协议:生成器函数返回的迭代器对象自动遵循迭代器协议(即实现next()方法)。
自定义迭代器:生成器函数可简化自定义迭代器的创建,无需手动实现next()逻辑。
yield*语法
委托迭代:yield*可将另一个生成器或可迭代对象的值依次yield出来,组合多个迭代器。
示例:function* generator1() { yield 1; yield 2; }function* generator2() { yield 3; yield* generator1(); // 委托给generator1 yield 4;}// 输出顺序:3 → 1 → 2 → 4
错误处理
try...catch捕获:生成器函数内部可通过try...catch处理yield抛出的错误。
示例:function* myGenerator() { try { yield 1; throw new Error('Error occurred'); } catch (error) { console.error('Caught:', error); } yield 3;}
与async/await的关系
底层依赖:async/await是生成器函数的语法糖,async函数返回Promise,await暂停执行直至Promise解决。
对比:async/await更简洁,但理解生成器函数有助于掌握异步编程原理。
适用场景
异步流程控制:如按顺序执行多个异步任务。
自定义迭代器:实现非标准迭代逻辑(如无限序列)。
状态机:通过yield划分状态转换逻辑。
惰性求吵敬旅值:延迟计算值,节省资源。
性能与调试
性能考虑:生成器函数因需保存执行状态,效率略低于普通函数,高并发场景需谨慎使用。
调试技巧:
使用console.log输出执行状态。
利用调试器单步执行。
通过try...catch定位错误。
生成器函数通过灵升凳活的暂停/恢复机制,为JS提供了强大的流程控制能力,尤其在异步编程和自定义迭代场景中表现突出。理解其原理有助于更高效地解决复杂编程问题。