js yield 实现
yield 在 JavaScript 中的实现
在 JavaScript 中,yield 是生成器函数(Generator Function)的关键字,用于暂停和恢复函数的执行。生成器函数通过 function* 语法定义,调用时返回一个生成器对象(Generator Object),该对象遵循迭代器协议。
基本语法
生成器函数通过 function* 声明,内部使用 yield 关键字暂停执行并返回一个值:
function* generatorExample() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorExample();
console.log(gen.next().value); // 输出 1
console.log(gen.next().value); // 输出 2
console.log(gen.next().value); // 输出 3
生成器的工作原理
- 生成器对象:调用生成器函数不会立即执行函数体,而是返回一个生成器对象。
next()方法:每次调用next()会恢复执行,直到遇到yield或return。- 返回值:
next()返回一个对象,包含value(yield的值)和done(是否执行完毕)。
示例:无限序列
生成器可以用于生成无限序列,例如斐波那契数列:

function* fibonacci() {
let a = 0, b = 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
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
与迭代器的关系
生成器对象实现了迭代器协议([Symbol.iterator]),可以直接用于 for...of 循环:
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
}
双向通信
yield 可以接收外部传入的值,通过 next(value) 传递:

function* twoWayCommunication() {
const name = yield 'What is your name?';
yield `Hello, ${name}!`;
}
const gen = twoWayCommunication();
console.log(gen.next().value); // "What is your name?"
console.log(gen.next('Alice').value); // "Hello, Alice!"
错误处理
可以通过 throw() 方法向生成器内部抛出错误:
function* errorHandling() {
try {
yield 1;
} catch (error) {
yield `Caught: ${error}`;
}
}
const gen = errorHandling();
console.log(gen.next().value); // 1
console.log(gen.throw('Oops!').value); // "Caught: Oops!"
异步生成器
生成器可以与 async/await 结合,用于异步操作:
async function* asyncGenerator() {
const data = await fetch('https://api.example.com/data');
yield data.json();
}
const gen = asyncGenerator();
gen.next().then(({ value }) => console.log(value));
总结
yield是生成器函数的核心,用于暂停和恢复执行。- 生成器对象通过
next()、throw()和return()方法控制。 - 适用于惰性求值、无限序列和异步编程场景。
通过生成器可以实现复杂的控制流,例如协程(Coroutine)或状态机(State Machine)。






