生成器函数是JavaScript中一类特殊的函数,它可以通过yield关键字暂停执行,在需要的时候再恢复执行,非常适合处理需要分步执行或者惰性计算的场景。下面我们就一步步学习如何创建和使用生成器函数。

生成器函数的基本定义方式
生成器函数和普通函数的区别是在function关键字后面加一个星号*,函数内部可以使用yield关键字来暂停执行,返回中间结果。定义生成器函数的语法如下:
// 基本生成器函数定义
function* simpleGenerator() {
yield '第一个值';
yield '第二个值';
yield '第三个值';
return '结束值';
}调用生成器函数的时候,不会立刻执行函数内部的代码,而是会返回一个生成器对象,这个对象符合迭代器协议,可以通过next()方法来逐步执行函数内部的逻辑。
yield关键字的作用
yield是生成器函数的核心关键字,它的作用是暂停函数的执行,并且把后面跟着的值作为当前next()调用的返回值。每次调用生成器对象的next()方法,函数会从上次暂停的位置继续执行,直到遇到下一个yield或者函数结束。
我们可以通过下面的示例来观察执行过程:
function* demoGenerator() {
console.log('开始执行');
const result1 = yield 10;
console.log('第一次恢复执行,接收到的值:', result1);
const result2 = yield 20;
console.log('第二次恢复执行,接收到的值:', result2);
return 30;
}
const gen = demoGenerator();
// 第一次调用next,执行到第一个yield暂停,返回{value:10, done:false}
console.log(gen.next());
// 第二次调用next,传入参数作为上一个yield的返回值,执行到第二个yield暂停
console.log(gen.next('传入值1'));
// 第三次调用next,传入参数作为第二个yield的返回值,执行到return结束
console.log(gen.next('传入值2'));
上面的代码执行后,输出结果如下:
开始执行
{ value: 10, done: false }
第一次恢复执行,接收到的值: 传入值1
{ value: 20, done: false }
第二次恢复执行,接收到的值: 传入值2
{ value: 30, done: true }生成器对象的迭代器特性
生成器对象本身是可迭代的,所以可以直接用for...of循环来遍历生成器产生的所有值,不过要注意,for...of只会遍历yield返回的值,不会遍历return返回的最终值。
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
return 4;
}
const gen = numberGenerator();
for (const num of gen) {
console.log(num);
}
// 输出:1 2 3生成器函数的常见使用场景
1. 实现自定义迭代器
如果我们需要让一个对象可以被迭代,除了实现Symbol.iterator方法,也可以用生成器函数来简化实现:
const customObj = {
data: [10, 20, 30, 40],
*[Symbol.iterator]() {
for (const item of this.data) {
yield item * 2;
}
}
};
for (const val of customObj) {
console.log(val);
}
// 输出:20 40 60 802. 处理异步流程
虽然现在async/await更常用,但生成器函数也可以配合执行器来处理异步逻辑,实现类似同步代码的写法:
function* asyncTaskGenerator() {
const res1 = yield new Promise(resolve => setTimeout(() => resolve('第一步结果'), 1000));
console.log(res1);
const res2 = yield new Promise(resolve => setTimeout(() => resolve('第二步结果'), 1000));
console.log(res2);
return '全部完成';
}
// 简单的生成器执行器
function runGenerator(gen) {
const generator = gen();
function handle(result) {
if (result.done) return result.value;
result.value.then(data => {
handle(generator.next(data));
});
}
handle(generator.next());
}
runGenerator(asyncTaskGenerator);
// 1秒后输出:第一步结果,再1秒后输出:第二步结果注意事项
- 生成器函数内部的
this指向和普通函数一致,但是如果生成器函数作为对象的方法,需要注意调用时的上下文。 yield关键字只能在生成器函数内部使用,在普通函数中使用会报错。- 生成器对象的
next()方法可以传入参数,这个参数会成为上一个yield表达式的返回值。 - 生成器函数执行完毕后,再次调用
next()会返回{value: undefined, done: true}。
JavaScript生成器函数Generatoryield迭代器修改时间:2026-05-29 23:17:59