生成器函数(function)调用后返回迭代器而不执行,需调用next()才开始运行并暂停于yield;yield可多次中断恢复、保留上下文,其表达式返回外部传入的值;适用于同步迭代,异步需async function配合for await...of。
function* 声明的函数就是生成器函数,它不是一次性返回全部结果,而是按需产出值,每次调用 next() 就执行到下一个 yield 并暂停。
这和普通函数有本质区别:普通函数一调用就跑完、返回一个值(或 undefined);生成器函数调用后返回一个迭代器对象,你得手动驱动它一步步走。
这是最容易误解的一点。写好 function* gen() { console.log('start'); yield 1; },然后执行 gen() —— 控制台什么都不会打。
因为:
gen() 只创建并返回一个迭代器,不进入函数体next()
function* gen() {
console.log('start');
yield 1;
yield 2;
}
const it = gen(); // 没输出
it.next(); // 输出 'start',返回 { value: 1, done: false }
yield 不是 return,可以多次中断恢复yield 会暂停执行,并把右侧表达式的值作为 value 返回;函数上下文(变量、执行位置)完整保留。下次 next() 时从中断处继续,不是重头来。
注意:yield 只能在生成器函数内部用,外层作用域写会报 SyntaxError: Unexpected strict mode reserved word。
yield
function 里用 yield
yield 表达式本身有返回值:外部传入 next(value) 的 value 会成为本次 yield 表达式的计算结果function* gen() {
const x = yield 'first';
console.log('x:', x); // x: 'from next'
yield 'second';
}
const it = gen();
it.next(); // { value: 'first', done: false }
it.next('from next'); // 输出 'x: from next',{ value: 'second', done: false }
它天然适配 for...of、Array.from()、展开运算符 [...gen()] 等可迭代协议场景,但要注意:如果生成器逻辑里有异步操作(比如 await),必须用 async function* —— 普通 function* 里不能直接 await,否则会当成字面量处理。
function* → 同步迭代,yield 是控制权让渡点async function* → 异步迭代,支持 yield + await,返回的是 AsyncIterator
for await...of 才能消费 async function* 产生的迭代器async function* asyncGen() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
}
for await (const x of asyncGen()) {
console.log(x); // 1, 然后 2
}
生成器函数的核心价值

done: true,后续 next() 全部返回 { value: undefined, done: true } —— 这个静默终止行为,比想象中更难调试。