SyntaxError:意外标识符(ES6中的生成器)
在阅读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
,但没有任何成功。
我不明白什么yield*
确实 ,但如果我在for
循环中使用它for
我得到:
alix@900X4C:~$ node --harmony test.js /home/alix/test.js:14 yield* suffix; ^ ReferenceError: yield is not defined
如果我用console.log()
replacefor中的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
解决scheme(谢谢@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); }
总结评论:你不能在正则函数中使用yield
,所以你不能在forEach
使用yield
。 这里是一个“生成器”的例子:
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); }
所以发电机本身就变成了一个单线!
你已经find了你的解决scheme,但是为了logging这里是另一个有点不同的例子,打印树中所有节点的types(我添加了一些深度和variables)
var nodes = { type: 'root', value: [ { type: 'char', value: 'a' }, { type: 'char', value: 'b' }, { type: 'char', value: [{type: 'int', value: 'c'}] }, ], }; var flattenTree = function* (root) { yield root.type; var subvalues = root.value; for(var i in subvalues) { var gen = flattenTree(subvalues[i]); val = gen.next(); while(!val.done) { if(val.value != undefined) yield val.value; val = gen.next(); } } } var printTree = function() { console.log("begin tree"); var generator = flattenTree(nodes); var next = generator.next(); while(!next.done) { console.log(next); next = generator.next(); } console.log("finish tree"); } printTree();
输出:
~/workspace/tmp$ ../node/node --harmony test-gen.js begin tree { value: 'root', done: false } { value: 'char', done: false } { value: 'char', done: false } { value: 'char', done: false } { value: 'int', done: false } finish tree