Los generadores son funciones que pueden salir y volver a entrar posteriormente. Su contexto (enlaces de variables) se guardará a través de reentradas.
Los generadores en JavaScript – especialmente cuando se combinan con Promesas – son una herramienta muy poderosa para la programación asíncrona, ya que mitigan – si no eliminan por completo – los problemas con las devoluciones de llamada, como el infierno de las devoluciones de llamada y la inversión de control. Sin embargo, una solución aún más simple a estos problemas se puede lograr con funciones asíncronas.
La llamada a una función generadora no ejecuta su cuerpo inmediatamente; en su lugar se devuelve un objeto iterador para la función. Cuando se llama al método next()
del iterador, el cuerpo de la función generadora se ejecuta hasta la primera expresión yield
, que especifica el valor a devolver del iterador o, con yield*
, delega en otra función generadora. El método next()
devuelve un objeto con una propiedad value
que contiene el valor cedido y una propiedad done
que indica si el generador ha cedido su último valor, en forma de booleano. La llamada al método next()
con un argumento reanudará la ejecución de la función del generador, sustituyendo la expresión yield
en la que se pausó la ejecución por el argumento de next()
.
Una sentencia return
en un generador, al ejecutarse, hará que el generador termine (es decir, la propiedad done
del objeto devuelto por ella se pondrá a true
). Si se devuelve un valor, se establecerá como la propiedad value
del objeto devuelto por el generador.
Al igual que una sentencia return
, un error es lanzado dentro del generador hará que el generador termine – a menos que sea capturado dentro del cuerpo del generador.
Cuando un generador está terminado, las llamadas posteriores next()
no ejecutarán ningún código de ese generador, sólo devolverán un objeto de esta forma: {value: undefined, done: true}
.