【发布时间】:2021-09-05 09:45:52
【问题描述】:
以下是我对 yield * 运算符的确切机制的理解,而不是 yield 在阅读文档并使用它后想到它:
在生成器函数返回的迭代器上调用next()时,如果遇到:
-
yield someFunction():它应该调用someFunction()并返回一个pair 对象,其返回值在value中,以及是否有更多指令进入done -
yield * someGenerator():它应该使用someGenerator()返回的迭代器,在其上调用next()函数并返回一个pair 对象,其中value从迭代器获得,done只到true如果两个迭代器都返回了done===true并且没有更多的指令来了
换句话说,yield * 将迭代器的下一步委托给另一个生成器函数。
因此我希望someFunction() 只是一个普通的生成器,即使它没有yield 语句,但只有return,它也会暂停其执行(以及它的调用者之一)声明甚至根本没有return 声明。
但好像不是这样的。
看看这个例子,我们在游戏流程中使用生成器,目标是每次我们yield,我们可以暂停执行以将新的游戏状态发送到客户端,例如。所以mainGameFlow 生成器将像函数调用一样委托给其他生成器,但我们希望在每一步之间暂停执行:
function* mainGameFlow() {
console.log(' (mainGameFlow) Will give money')
yield* giveMoney()
console.log(' (mainGameFlow) Will give card')
yield* giveCard()
}
function* giveMoney() {
console.log(' (giveMoney) Giving money to player')
}
function* giveCard() {
console.log(' (giveCard) Giving card to player')
// if(card has effect)...
console.log(' (giveCard) Will apply card\'s effects')
yield* applyCardEffect()
}
function* applyCardEffect() {
console.log(' (applyCardEffect) Applying card effect')
}
console.log('Will get iterator from generator')
const iterator = mainGameFlow()
console.log('Will launch iterator first step')
iterator.next()
console.log('Iterator paused')
我希望在mainGameFlow 迭代器上对next() 的第一次调用会在记录“给玩家钱”之后暂停其执行。因为当一个生成器刚刚返回时,它就像它产生时一样停止它的流动。
但在这里,所有的日志记录行都到达了,主迭代器只有在整个流程发生后才暂停。
我的问题是:你认为我的代码有问题吗?如果没有,您是否知道比 yield * 上的 MDN 更好的文档,可以清楚地理解为什么在这个用例中流程会继续?
【问题讨论】:
-
生成器函数在对第一个 yield 或 return 语句的第一个 next() 调用上运行。正如您所说,“yield* 将迭代器的下一步委托给另一个生成器函数。”
-
如果您将 yield 和 return 视为生产者,将 .next() 视为消费者,这可能会更容易理解。每次消费都恰好匹配一种生产。
-
"
someFunction()只是一个普通的生成器" - 你的意思是someGenerator()?
标签: javascript return generator yield