Código
En este ejemplo primero definimos la función generadora.
function* generarSecuencia() { yield 5 + 6; yield String.fromCharCode(parseInt("1110000", 2).toString(10)); yield 3 + 4; return 14; } var secuencia = generarSecuencia(); alert( JSON.stringify(secuencia.next()) ); alert( JSON.stringify(secuencia.next()) ); alert( JSON.stringify(secuencia.next()) ); alert( JSON.stringify(secuencia.next()) ); alert( JSON.stringify(secuencia.next()) );
Definimos cada campo precedido por la keyword yield.
Retornamos la ejecución.
En el parámetro del alert invocamos next() sobre la función y utilizamos JSON.stringify para convertir el objeto en un string para ver exactamente que contiene cada objeto retornado:
{"value":11,"done":false}
{"value":"p","done":false}
{"value":7,"done":false}
{"value":14,"done":true}
{"done":true}
Cuando haces una llamada a este tipo de funciones su código no es ejecutado directamente, en su defecto, retorna un objeto generador que maneja la ejecución.
El método next() nos retornará un objeto con la propiedad/key value que contiene el valor generado por la instrucción alcanzada por el objeto generator y otra propiedad de tipo booleano primitivo en el mismo objeto retornado llamada done. Esta propiedad nos indica si la función retornó su ejecución al código de llamada a través del objeto generator. Es decir, si la función ha finalizado.
Esta propiedad podemos utilizarla como iterador para evaluar las instrucciones del cuerpo de la función.
Cuando ocurre un error en uno de los campos se retornará también la propiedad done = true a menos que se implemente manejo de excepciones sobre el campo o la expresión.
Las propias funciones generadoras son iterables y podemos usar expresiones de la índole de for (valor of generador) para recorrer sus instrucciones.
Es también una buena forma remplazar callbacks evitando los problemas comunes de los callbacks en la programación asíncrona.
La funciones generadoras también permiten realizar bucles infinitos.
Código
function* generarSecuenciaInfinita() { var inicial = -1; while(1) { yield inicial += 2; } } var secuencia = generarSecuenciaInfinita(); var valor = 0; var nImpares = ""; var nPares = ""; while(valor < 30) { valor = secuencia.next().value; if(valor < 30) { nImpares += valor + " "; nPares += "" + (+valor + 1) + " "; } } document.write("Números Impares menores que 30: " + nImpares); document.write("<br />Números Pares menores que 30: " + nPares);