SyntaxError: identifiant inattendu (générateurs dans ES6)

Je viens avec cette expérience simple après avoir lu la documentation sur les générateurs de 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); } 

L'exécuter sur node.js v0.11.9 avec l' --harmony drapeau --harmony produit l'erreur suivante:

 alix@900X4C:~$ node --version v0.11.9 alix@900X4C:~$ node --harmony test.js /home/alix/test.js:14 yield suffix; ^^^^^^ SyntaxError: Unexpected identifier 

J'ai également essayé d'utiliser for ... in ... et le mot let clé let au lieu de var , mais sans succès.

Je ne comprends pas ce que le yield* fait exactement , mais si je l'utilise dans la boucle for , je reçois plutôt:

 alix@900X4C:~$ node --harmony test.js /home/alix/test.js:14 yield* suffix; ^ ReferenceError: yield is not defined 

Si je remplace le rendement dans le pour avec console.log() il produit a , b et c . Qu'est-ce que je fais mal?


modifier

Voici un générateur minimaliste, montrant que node.js sait ce qu'il faut faire avec les générateurs:

 function* alpha() { yield 'a'; yield 'b'; yield 'c'; } for (var suffix of alpha()) { console.log(suffix); } 

Sortie:

 alix@900X4C:~$ node --harmony y.js a b c 

Solution (merci @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); } 

    Résumant les commentaires: vous ne pouvez pas utiliser le yield dans une fonction régulière , de sorte que vous ne pouvez pas utiliser le yield avec pour forEach . Voici un exemple de "généré":

     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) } 

    MISE À JOUR En outre, le problème original peut être résolu assez élégamment en utilisant un tel assistant:

     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); } 

    Le générateur lui-même devient un one-liner!

    Vous avez trouvé votre solution, mais pour l'enregistrement ici, il y a un autre exemple un peu différent qui permet d'imprimer les types de tous les noeuds de l'arbre (j'ai ajouté de la profondeur et des vars)

     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(); 

    Les sorties:

     ~/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