Me pregunto acerca de los inconvenientes de reiniciar un generador delegándose al final.
function* myGenerator(){ yield "value1"; yield "value2"; yield "value3"; yield "value4"; yield* myGenerator(); } const generate = myGenerator(); for (let i = 0; i<15; i++){ document.getElementById("output").innerHTML += generate.next().value + "["+i +"]"+"<br />"; }
<div id="output"></div>
Un inconveniente que me vino a la mente es la posibilidad de un bucle infinito si se usa como iterador. Sin embargo, se puede omitir con un contador.
function* myGenerator(c){ let counter = c? c: 0; yield "value1"; yield "value2"; yield "value3"; yield "value4"; counter++; if (counter < 3){ yield* myGenerator(counter); } } const generate = myGenerator(); for (let val of generate){ document.getElementById("output").innerHTML += val+ "<br />"; }
<div id="output"></div>
Las llamadas recursivas consumirán la pila de llamadas y, en cada rendimiento, esta pila debe guardarse y restaurarse.
Su ejemplo es un caso de recursión de cola, por lo que es fácil de reescribir como un bucle:
function* myGenerator() { while (true) { yield "value1"; yield "value2"; yield "value3"; yield "value4"; } } const generate = myGenerator(); for (let i = 0; i < 15; i++) { document.getElementById("output").innerHTML += generate.next().value + "[" + i + "]<br>"; }
<div id="output"></div>
En cuanto a evitar que intente consumir una serie infinita, podría usar una función genérica para eso.
No relacionado, pero solo asignaría una vez a innerHTML
:
function* myGenerator() { while (true) { yield "value1"; yield "value2"; yield "value3"; yield "value4"; } } function* islice(iterator, count) { for (let value of iterator) { if (--count < 0) return; yield value; } } const generate = islice(myGenerator(), 15); const values = Array.from(generate, (value, i) => value + "[" + i + "]"); document.getElementById("output").innerHTML += values.join("<br>");
<div id="output"></div>
function* myGenerator() { // when nothing to yield temply yield* myGenerator(); }
var cur_counter = 0; function* myGenerator() { cur_counter++; console.log("current count of generator: " + cur_counter); yield 1; yield* myGenerator(); cur_counter--; // will never be called }
EDITAR
Pila de llamadas: