JSGenerator函数yield表达式示例详解

JSGenerator函数yield表达式示例详解
最新回答
不顾离别

2026-06-03 14:14:47

Generator函数是一种特殊的函数,可以在执行过程中暂停和恢复,这使得函数的执行逻辑可以被分段处理。它通过yield表达式实现暂停与恢复。在使用时,Generator函数不会立即执行,而是返回一个遍历器对象。每次调用该对象的next方法时,函数会从上次暂停的地方继续执行,直到遇到下一个yield表达式或return语句后暂停。例如:

function* gen() {
yield 'hello'
yield 'world'
return 'ending'
}

let it = gen()
it.next() // {value: "hello", done: false}
it.next() // {value: "world", done: false}
it.next() // {value: "ending", done: true}
it.next() // {value: undefined, done: true}

yield表达式仅限于Generator函数内部,如果在普通函数中使用会报错。yield表达式在表达式中必须用括号包裹,如下所示:

function* demo() {
console.log('Hello' + yield);
console.log('Hello' + (yield 123));
console.log('Hello' + (yield));
console.log('Hello' + (yield 123));
}

yield*表达式用于在Generator函数中调用另一个Generator函数。如果不使用yield*,调用另一个Generator函数将不会生效。例如:

function* foo() {
yield 'aaa'
yield 'bbb'
}
function* bar() {
yield* foo()
yield 'ccc'
yield 'ddd'
}

let iterator = bar()
for(let value of iterator) {
console.log(value)
}

在调用Generator函数的next方法时,可以传递参数,这将作为上一个yield表达式的返回值。例如:

function* gen(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 3)
return x + y + z
}

let it = gen(5)
console.log(it.next())
console.log(it.next())
console.log(it.next())

Symbol.iterator属性用于创建可迭代的对象。Generator函数可以被赋予对象的Symbol.iterator属性,从而让该对象具有Iterator接口。例如:

let obj = {}
function* gen() {
yield 4
yield 5
yield 6
}
obj[Symbol.iterator] = gen
for(let value of obj) {
console.log(value)
}

Generator函数还提供了return方法,可以返回给定的值并结束遍历。例如:

function* gen() {
yield 1
yield 2
yield 3
}
let it = gen()
it.next()
it.return('ending')
it.next()

在实际应用中,Generator函数可以用于实现复杂的逻辑控制,如抽奖、长轮询等场景。例如:

function* remain(count) {
while(count > 0) {
count--
yield draw(count)
}
}

function draw(count) {
console.log(`剩余${count}次`)
}

let startDrawing = remain(6)
let btn = document.createElement('button')
btn.id = 'start'
btn.textContent = '开始抽奖'
document.body.appendChild(btn)
document.getElementById('start').addEventListener('click', function(){
startDrawing.next()
}, false)

通过使用Generator函数,可以更灵活地控制程序的执行流程,提高代码的可读性和可维护性。