Hace poco he escrito sobre que V8 ya soporta generadores en el bleeding_edge y que se pueden usar ya desde node con las últimas versiones inestables y que con eso se podrá escribir código asíncrono lineal desde javascript (sin anidar millones de funciones).

¿Qué son los generadores?

Enlace a la wikipedia: http://en.wikipedia.org/wiki/Generator_(computer_programming)

Básicamente un generador es como un iterador pero implementado como una función que va generando valores que otra función consume. Por ejemplo, podemos tener una función que genera un listado infinito de números primos. Podríamos hacer una función que generase un array con un montón de números primos, pero además de que ocuparía bastante memoria si generamos una lista grande, la lista sería limitada. Hay lenguajes que soportan la interfaz Iterable que permite crear una clase con un método que se va llamando en cada paso.

Los generadores llevan muchísimo tiempo en el mundo de la programación, pero si el/los lenguajes que sueles usar no soportan generadores, es fácil que no los hayas usado nunca y no supieses lo que eran. Para la gente que ha usado python, ruby o C# es bastante natural. Ahora dos de los lenguajes más populares del mundo los van a implementar: PHP 5.5 y JavaScript Harmony/EcmaScript 6. Así que es un buen momento para empezar a familiarizarse con ellos.

Un generador tradicional se puede considerar como un productor de información, y el código encargado de obtener los resultados paso a paso bien con un método next() o bien con un for each, se puede considerar como un consumidor de información.

Veamos aquí un ejemplo con la función de python xrange implementada en javascript:

// Producer
function xrange*(min, max) { while (min < max) yield min++; }
// Consumer
for (let v of xrange(10, 20000)) console.log(v);

Cada vez que se llega a la expresión yield, se para la ejecución de la función (manteniendo el estado y permitiendo retomarla después justo donde se quedó) y genera un valor.

Generadores bidireccionales

Los generadores de Python, C# (no sé si también de ruby), son generadores unidireccionales. El generador hace de productor y ya está, no obtiene información del código que ha llamado al generador.

En JavaScript y en PHP los generadores son bidireccionales. Cada vez que el generador genera un valor, puede obtener de vuelta otro valor o incluso lanzarse una excepción dentro del código del generador.

En JavaScript si llamamos a un generador obtenemos un objeto con los métodos:

var generatedValue = generator.next();
var generatedValue = generator.send(value);
var generatedValue = generator.throw(err);
generator.close();

La primera vez tenemos que llamar al método next() para obtener el primer valor del generador. El generador parará la ejecución justo donde el yield y permitirá mandar un valor de vuelta al generador mediante el método send(), o lanzar una excepción mediante el método throw(). Si no necesitamos mandar ningún valor de vuelta al generador, volveríamos a llamar a next().

El hecho de que el canal sea bidireccional y que se puedan pasar mensajes/objetos entre el generador y el consumidor permite simular el comportamiento await/async de .NET 4.5.