为什么 javascript 生成器函数的 yield 语句返回 .next() 的参数?
Why is yield statement of a javascript generator function returning parameters of .next()?
我偶然发现了 generator functions on MDN,令我困惑的是以下示例:
function* logGenerator() {
console.log(yield);
console.log(yield);
console.log(yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next();
gen.next('pretzel'); // pretzel
gen.next('california'); // california
gen.next('mayonnaise'); // mayonnaise
我不明白的是为什么 yield
语句是 console.log
的参数 returns 参数传递给生成器的 .next()
方法.发生这种情况是因为空 yield
必须 return .next()
方法的第一个参数的值吗?
我还尝试了更多示例,这些示例似乎证实了上述说法,例如:
gen.next(1,2,3); // the printed value is 1, the 2 and 3 are ignored
// and the actual yielded value is undefined
还有没有办法在生成器函数体内访问 .next()
方法的更多参数?
我注意到的另一件事是,虽然 yield 语句将这些值 returning 到 console.log
,但它们实际上并没有作为生成器的输出产生。我必须说我觉得它很混乱。
[rv] = yield [expression];
expression 通过迭代器协议将生成器函数的值定义为 return。如果省略,则 undefined 被 returned 代替。
rv Returns 传递给生成器的 next() 方法以恢复其执行的可选值。
基本上您是在打印出您发送的参数以继续执行。
好问题。我认为阅读有关 .next()
方法的 MDN 最有帮助。您可以在生成器函数本身(即 yield 1
)中定义要传递的值,或者通过 next()
传递值,例如 gen.next(1)
next()
方法本身 returns 一个对象,具有属性 value
和一个布尔值 done
表示生成器函数是否完成(即耗尽可用输出,现在将只输出 undefined
作为一个值)。
也就是说,有两种方法可以访问/传递 value
。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next
混淆来自于 yield
和 next
具有不同语法的事实,而它们实际上做的是同一件事。生成器和它的调用者是对称的(这就是为什么它们被称为 "co"-例程而不是 "sub"-例程)。这两个功能都可以被认为是通过通信通道连接的,并且可以完成它们的工作或等待通道中的传入消息。唯一的区别是生成器最初是睡眠的(也就是说,在它的顶部有一个隐式的 "listen" 命令),而调用者最初是清醒的。
yield
和next
都做同样的事情三件事:
- 将其参数写入通道
- 入睡并收听传入消息
- 发出传入的消息作为它的值并唤醒(即,继续它们下面的内容)
插图:
_ = console.log.bind(console)
function *gen() {
_('gen: good morning')
_('gen: sending hi')
_('gen: zzz')
p = yield 'hi'
_('gen: awake! got', p)
_('gen: now sending fine')
_('gen: zzz')
p = yield 'fine'
_('gen: awake! got', p) // ***
}
function main() {
var g = gen()
_('main: sending knock knock')
_('main: zzz')
r = g.next('knock knock')
_('main: awake! got', r)
_('main: sending how r u')
_('main: zzz')
r = g.next('how r u')
_('main: awake! got', r)
}
main()
请注意,由于写入先于读取,因此发送给生成器的第一条消息丢失了。它仅用于唤醒生成器。还要注意我们是如何让生成器处于休眠状态的,所以 ***
行没有到达。
我偶然发现了 generator functions on MDN,令我困惑的是以下示例:
function* logGenerator() {
console.log(yield);
console.log(yield);
console.log(yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next();
gen.next('pretzel'); // pretzel
gen.next('california'); // california
gen.next('mayonnaise'); // mayonnaise
我不明白的是为什么 yield
语句是 console.log
的参数 returns 参数传递给生成器的 .next()
方法.发生这种情况是因为空 yield
必须 return .next()
方法的第一个参数的值吗?
我还尝试了更多示例,这些示例似乎证实了上述说法,例如:
gen.next(1,2,3); // the printed value is 1, the 2 and 3 are ignored
// and the actual yielded value is undefined
还有没有办法在生成器函数体内访问 .next()
方法的更多参数?
我注意到的另一件事是,虽然 yield 语句将这些值 returning 到 console.log
,但它们实际上并没有作为生成器的输出产生。我必须说我觉得它很混乱。
[rv] = yield [expression];
expression 通过迭代器协议将生成器函数的值定义为 return。如果省略,则 undefined 被 returned 代替。
rv Returns 传递给生成器的 next() 方法以恢复其执行的可选值。
基本上您是在打印出您发送的参数以继续执行。
好问题。我认为阅读有关 .next()
方法的 MDN 最有帮助。您可以在生成器函数本身(即 yield 1
)中定义要传递的值,或者通过 next()
传递值,例如 gen.next(1)
next()
方法本身 returns 一个对象,具有属性 value
和一个布尔值 done
表示生成器函数是否完成(即耗尽可用输出,现在将只输出 undefined
作为一个值)。
也就是说,有两种方法可以访问/传递 value
。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next
混淆来自于 yield
和 next
具有不同语法的事实,而它们实际上做的是同一件事。生成器和它的调用者是对称的(这就是为什么它们被称为 "co"-例程而不是 "sub"-例程)。这两个功能都可以被认为是通过通信通道连接的,并且可以完成它们的工作或等待通道中的传入消息。唯一的区别是生成器最初是睡眠的(也就是说,在它的顶部有一个隐式的 "listen" 命令),而调用者最初是清醒的。
yield
和next
都做同样的事情三件事:
- 将其参数写入通道
- 入睡并收听传入消息
- 发出传入的消息作为它的值并唤醒(即,继续它们下面的内容)
插图:
_ = console.log.bind(console)
function *gen() {
_('gen: good morning')
_('gen: sending hi')
_('gen: zzz')
p = yield 'hi'
_('gen: awake! got', p)
_('gen: now sending fine')
_('gen: zzz')
p = yield 'fine'
_('gen: awake! got', p) // ***
}
function main() {
var g = gen()
_('main: sending knock knock')
_('main: zzz')
r = g.next('knock knock')
_('main: awake! got', r)
_('main: sending how r u')
_('main: zzz')
r = g.next('how r u')
_('main: awake! got', r)
}
main()
请注意,由于写入先于读取,因此发送给生成器的第一条消息丢失了。它仅用于唤醒生成器。还要注意我们是如何让生成器处于休眠状态的,所以 ***
行没有到达。