什么是 yield?
yield 关键字只能在生成器函数中使用。生成器函数是一种特殊的函数,使用 function* 声明。当生成器函数执行到 yield 表达式时,它会暂停执行,并将 yield 后面的值返回给调用者。重要的是,函数的状态会被保存,以便稍后可以从暂停的地方继续执行。
生成器函数的基本语法:
javascript
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const generator = myGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
function* myGenerator(): 声明一个生成器函数。yield 1;: 暂停函数执行,并返回1。generator.next(): 调用next()方法恢复函数的执行,并返回一个包含value和done属性的对象。value属性是yield表达式的值,done属性表示生成器函数是否已经执行完毕。
双向通信 :
yield不仅能向外传递值,还能通过next(value)接收外部输入:
javascript
function* calculator() {
const a = yield 'Enter a:';
console.log(a)
const b = yield 'Enter b:';
console.log(b)
return a + b;
}
const cal = calculator();
cal.next(); // {value: 'Enter a:', done: false}
cal.next(2); // {value: 'Enter b:', done: false}
cal.next(3); // {value: 5, done: true}
这种特性使得生成器可以动态响应外部逻辑
yield 的强大之处:
-
控制迭代过程:
yield允许你自定义迭代过程,按需生成值。这对于处理大型数据集或无限序列非常有用,可以避免一次性加载所有数据到内存中。javascriptfunction* infiniteSequence() { let i = 0; while (true) { yield i++; } } const sequence = infiniteSequence(); console.log(sequence.next().value); // 0 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 2 // ... 无限循环 -
实现状态机:
yield可以用于实现状态机,控制程序在不同状态之间的转换。javascriptfunction* stateMachine() { let state = 'start'; while (true) { switch (state) { case 'start': console.log('Starting...'); state = yield 'waiting'; break; case 'waiting': console.log('Waiting for input...'); state = yield 'processing'; break; case 'processing': console.log('Processing data...'); state = yield 'done'; break; case 'done': console.log('Done!'); return; default: console.log('Invalid state!'); return; } } } const machine = stateMachine(); console.log(machine.next()); // Starting... { value: 'waiting', done: false } console.log(machine.next('processing')); // Waiting for input... { value: 'processing', done: false } console.log(machine.next('done')); // Processing data... { value: 'done', done: false } console.log(machine.next()); // Done! { value: undefined, done: true }