Funciones Generadoras en ECMAScript6

Como posiblemente sabes, ECMAScript6 es la nueva versión del estándar que utilizará JavaScript a partir de junio de 2015. Hablé de ello en una anterior entrada con algunas de las novedades que trae el estándar.

Recientemente he visto otras de las novedades del estándar, las funciones generadoras (Generators). Son funciones especiales (también se declaran de manera diferente con function *) y de las que se puede salir y entrar varias veces con resultados diferentes. Me ha parecido interesante, y quería compartirlo

Llamar a un Generator no ejecuta la función completa inmediatamente, si no que devuelve un objeto Iterator el cúal devuelve el valor del iterador o delega a otra función Generator a través de la variable yield. NOs serviremos del método next() para seguir iterando.

yield es una palabra reservadaque devuelve en forma de objeto el valor que asignamos a yield y la propiedad done que nos indica a través de true o false si el generador ya no tiene más valores que mostrar.

Veamos un ejemplo:

function *soyUnGenerador(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

var gen = soyUnGenerador(1);
console.log(gen.next());
//  Object {value: 2, done: false}
console.log(gen.next());
//  Object {value: 3, done: false}
console.log(gen.next());
//  Object {value: 4, done: false}
console.log(gen.next());
//  Object {value: undefined, done: true}

Cada vez que hemos llamado a next() ha entrado en la función y ha ejecutado una línea de las declaraciones de yield. Cuando ya no había más declaraciones, la función devuelve el valor undefined y el atributo done a false.

Esto puede ser utilizado para recursión, llamadas asíncronas, iteradores de arrays, etc..

En la documentación de Mozilla podemos ver un ejemplo de recursión con generadores con el número de Fibonacci:

function *fibonacci() { 
	let [anterior, actual] = [0, 1];
    for (;;) { 
    	[anterior, actual] = [actual, anterior + actual]; 
        yield actual; 
    }
}

let seq = fibonacci();
console.log(seq.next().value) // 1
console.log(seq.next().value) // 2
console.log(seq.next().value) // 3
console.log(seq.next().value) // 5
console.log(seq.next().value) // 8
...

Para complementar esto, comparto una charla sobre generadores que dió Sergio Arbeo en MadridJS hace ya un tiempecillo hablando de esto.

Imagen de cabecera: Modernweb


¿Quieres contactar conmigo personalmente? Puedes hacerlo por email a través de Earn.com. Tiene asociado un coste de $20, qué sólo se te cobrará cuando responda.

Desarrollador web Frontend y apasionado de JavaScript. Aquí te enseño todo lo que aprendo y conozco sobre JavaScript y la programación web en general.

¿Te gusta lo que lees?
Apúntate a mi boletín, newsletter, lista de correo o como quieras llamarlo. Sólamente envío 1 email al mes con lo más relevante. ¿Te apuntas?