La especificación de borrador de ECMAScript 6 ya dio lugar a muchas alegrías para el desarrollador moderno de JavaScript. Abordamos algunas clases nuevas de colecciones y los bucles de iteración de for..of
en una publicación anterior. En esta publicación, hablaremos sobre algo que va de la mano con los bucles for..of
: las funciones de generador.
Ya hay un host de excelente material que explica por qué y cómo usar generadores. En pocas palabras, los generadores son funciones especiales que crean iteradores, mientras que los iteradores son objetos que tienen un método next()
, al que se puede llamar para obtener un valor. Dentro de una función de generador, la palabra clave yield
proporciona el valor para next()
. Con yield
, se suspende la ejecución de la función del generador y se mantiene el estado hasta que se vuelve a llamar a next()
. A partir de ese momento, el código comienza a crearse de nuevo y continúa, hasta yield
otro valor (o hasta que finalice la función del generador). Existen varios casos de uso canónicos para las funciones del generador, como usarlas para iterar sobre los números en la secuencia de Fibonacci.
Ahora que ya no explicarás los conceptos básicos, profundicemos en el ejemplo de JavaScript que abarca algunos de los problemas, o “bits complejos”, de trabajar con generadores. Hay muchos comentarios en todo el documento, y puedes experimentar con la versión publicada del código antes de leerlo:
¿Cuáles son algunas de las conclusiones principales del código?
Primero, la construcción de un generador da como resultado un iterador único con su propio estado distinto, y puedes pasar parámetros al constructor del generador que puede controlar el comportamiento.
En segundo lugar, puedes pasar un parámetro cuando llamas al método next()
de un iterador, y ese valor se asignará a lo que esté en el lado izquierdo de la sentencia yield
de la invocación anterior del iterador. Esta es una excelente manera de variar el resultado del iterador. Aquí, lo usamos para controlar si la palabra que se genera está en mayúsculas o no. Si quieres influir en el primer valor generado, hazlo a través de un parámetro al constructor del generador.
Por último, los generadores pueden producir iteradores finitos o infinitos. Si trabajas con un iterador infinito, asegúrate de tener algún tipo de condición de terminal basada en el valor yield
ed; es muy fácil escribir bucles infinitos por accidente, en especial cuando se usa for..of
para la iteración. Si trabajas con un iterador finito a través de llamadas a next()
, la propiedad .done
del objeto que se muestra indica si la iteración se completó.
Esperamos que este ejemplo, junto con los otros recursos disponibles en la Web, genere entusiasmo y te haga pensar cómo puedes usar generadores en tu propio código. Las versiones de Firefox que comienzan con la 31 y Chrome que comienzan con 39 admiten generadores de forma nativa. El proyecto Regenerator ofrece compatibilidad con el generador para otros navegadores y también es posible usar Traceur.
Agradecemos a Erik Arvidsson por su ayuda en la revisión de este artículo.