在阅读了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); }
在node.js v0.11.9上运行它并--harmony
设置了标志会产生以下错误:
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
,但没有任何成功.
我不明白究竟yield*
是什么,但如果我在for
循环中使用它我会得到:
alix@900X4C:~$ node --harmony test.js /home/alix/test.js:14 yield* suffix; ^ ReferenceError: yield is not defined
如果我用for console.log()
输出替换for中的yield 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
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); }
vkurchatkin.. 23
总结注释:你不能使用yield
一个内部定期的功能,所以你不能使用yield
与forEach
.这里有一个"发电机"foreach的例子:
function * foreach (arr, fn) { var i for (i = 0; i < arr.length; i++) { yield * fn(arr[i]) } } function * gen (number) { yield number + 1 yield number + 2 yield number + 3 } function * other () { yield * foreach([1, 2, 3], gen) } for (var i of other()) { console.log(i) }
更新 使用这样的助手也可以非常优雅地解决原始问题:
var nodes = { type: 'root', value: [ { type: 'char', value: 'a' }, { type: 'char', value: 'b' }, { type: 'root', value: [ { type: 'char', value: 'c' }, { type: 'char', value: 'd' }, { type: 'char', value: 'e' }, ] }, ], } function * foreach (arr, fn) { var i for (i = 0; i < arr.length; i++) { yield * fn(arr[i]) } } function * value (val) { yield val } function * recursiveGenerator(node) { yield * node.type === 'root' ? foreach(node.value, recursiveGenerator) : value(node.value) } for (var generated of recursiveGenerator(nodes)) { console.log(generated); }
所以发电机本身就变成了单线!
总结注释:你不能使用yield
一个内部定期的功能,所以你不能使用yield
与forEach
.这里有一个"发电机"foreach的例子:
function * foreach (arr, fn) { var i for (i = 0; i < arr.length; i++) { yield * fn(arr[i]) } } function * gen (number) { yield number + 1 yield number + 2 yield number + 3 } function * other () { yield * foreach([1, 2, 3], gen) } for (var i of other()) { console.log(i) }
更新 使用这样的助手也可以非常优雅地解决原始问题:
var nodes = { type: 'root', value: [ { type: 'char', value: 'a' }, { type: 'char', value: 'b' }, { type: 'root', value: [ { type: 'char', value: 'c' }, { type: 'char', value: 'd' }, { type: 'char', value: 'e' }, ] }, ], } function * foreach (arr, fn) { var i for (i = 0; i < arr.length; i++) { yield * fn(arr[i]) } } function * value (val) { yield val } function * recursiveGenerator(node) { yield * node.type === 'root' ? foreach(node.value, recursiveGenerator) : value(node.value) } for (var generated of recursiveGenerator(nodes)) { console.log(generated); }
所以发电机本身就变成了单线!