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,它会输出abc 。 我究竟做错了什么?


编辑

这是一个简约的生成器,显示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 
Interesting Posts