【发布时间】:2019-05-08 17:30:20
【问题描述】:
我在阅读documentation on generators from MDN后想出了这个简单的实验:
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'char', value: 'c' },
],
};
function* recursiveGenerator(node) {
if (node.type === 'root') {
node.value.forEach(function (subnode) {
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
});
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
在带有--harmony 标志集的node.js v0.11.9 上运行它会产生以下错误:
alix@900X4C:~$ node --version
v0.11.9
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield suffix;
^^^^^^
SyntaxError: Unexpected identifier
我也尝试使用for ... in ... 和let 关键字代替var,但没有任何成功。
我不明白 what yield* does exactly,但如果我在 for 循环中使用它,我会得到:
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield* suffix;
^
ReferenceError: yield is not defined
如果我将 for 中的 yield 替换为 console.log(),它会输出 a、b 和 c。我做错了什么?
编辑
这是一个简约的生成器,表明 node.js 知道如何使用生成器:
function* alpha() {
yield 'a';
yield 'b';
yield 'c';
}
for (var suffix of alpha()) {
console.log(suffix);
}
输出:
alix@900X4C:~$ node --harmony y.js
a
b
c
解决方案(感谢@Andrew)
function* recursiveGenerator(node) {
if (node.type === 'root') {
for (var i = 0; i < node.value.length; ++i) {
var subnode = node.value[i];
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
}
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
【问题讨论】:
-
我对这里随机出现的
*s 有点困惑。这些实际上在您的代码中吗?它们似乎不是您链接的规范的一部分。 -
@ChrisHayes:我添加了另一个链接(在问题中查找
yield*)。据我所知,function* ...是一个生成器函数(即包含yield关键字的函数),yield*是将生成器委托给另一个生成器的方式(我无法让它工作)。跨度> -
知道了,谢谢。对于
yield*,从错误消息来看,我认为节点期望yield是一个变量名。在这两种情况下,我肯定认为它没有被识别为关键字。 -
我对生成器还不够熟悉,因此无法发布答案,但我相信您的问题出在
forEach()。这会创建自己的范围(如setTimeout())。如果您将其更改为for (var i = 0; i < node.value.length; i++),您应该会看到它工作正常。 -
@Andrew 好地方。海事组织值得回答。好奇该节点在这里没有输出更好的错误消息,但我想
yield还为时过早。
标签: javascript node.js generator yield ecmascript-harmony