阅读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上运行它会产生以下错误:
--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 ...and let关键字代替var,但是没有成功。
for ... in ...
let
var
我不明白到底yield*是什么,但是如果我在for循环中使用它,我会得到:
yield*
for
alix@900X4C:~$ node --harmony test.js /home/alix/test.js:14 yield* suffix; ^ ReferenceError: yield is not defined
如果我用console.log()输出替换for中的收益a,则b和c。我究竟做错了什么?
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
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); }
总结注释:不能yield在 常规 函数中使用,因此不能yield与一起使用forEach。这里是“生成的” foreach的示例:
yield
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); }
因此,发电机本身变成了单线!