A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Generators

19/42
Recursos

Los generadores son funciones especiales, pueden pausar su ejecuci贸n y luego volver al punto donde se quedaron recordando su scope.

Algunas de sus caracter铆sticas:

  • Los generadores regresan una funci贸n.
  • Empiezan suspendidos y se tiene que llamar next para que ejecuten.
  • Regresan un value y un boolean done que define si ya terminaron.
  • yield es la instrucci贸n que regresa un valor cada vez que llamamos a next y detiene la ejecuci贸n del generador.

Aportes 101

Preguntas 13

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

apuntes de la clase:

No son apuntadores.
No son apuntadores.
No son apuntadores.
No son apuntadores.
XD

Esta es mi segunda vez en el curso y la verdad ahora lo he entendido mejor. Si esta es tu primera vez definitivamente debes tomar el curso como m铆nimo dos veces para que los conocimientos tomen base en el cerebro y se entiendan de una mejor forma.

Archivo en blanco para esta clase:

<html>
  <head>
    <title>Generators</title>
  </head>

  <body>
    <a href="/ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>

    <script>
      // Los generadores son funciones de las que se puede salir y volver a entrar.
      // Su contexto (asociaci贸n de variables) ser谩 conservado entre las reentradas.
      // Cada vez que llamamos next, la ejecuci贸n del generador va a continuar hasta el proximo yield

      // Podemos hacer generadores infinitos.

      // Cuando llamamos next tambi茅n podemos pasar valores que la funci贸n recibe.

      // Ahora hagamos un ejemplo un poco m谩s complejo: la secuencia fibonacci
    </script>
  </body>
</html>

Generador

El objecto Generador es retornado por generator function y conforma tanto un protocolo iterable como un protocolo iterador.

Sintaxis

function* gen() { 
  yield 1;
  yield 2;
  yield 3;
}

var g = gen(); // "Generator { }"

M茅todos

Generator.prototype.next()

Retorna el valor ofecido por la expresi贸n yield

Generator.prototype.return()

Retorna el valor dado y finaliza el generador.

Generator.prototype.throw()

Lanz谩 un error al generador

Ejemplo

Un iterador infinito

function* idMaker() {
	    var index = 0;
	    while(true)
	        yield index++;
	}

	var gen = idMaker(); // "Generator { }"

	console.log(gen.next().value); // 0
	console.log(gen.next().value); // 1
	console.log(gen.next().value); // 2
	// ...

Tambien el yield podemos usarlo para delegar el siguiente next() a otro generador usando yield*, ejemplo:

function* generator(){
	yield 1
	yield* anotherGenerator() //delega a la funcion anotherGenerator()
	yield 2
}

function* anotherGenerator(){
	yield 5
	yield 10
	yield 15
}

const gen = generator()

gen.next().value // 1
gen.next().value // 5
gen.next().value // 10
gen.next().value // 15
gen.next().value // 2

Si con yield se detiene la ejecuci贸n de esa funcion en donde queda la otra parte de esa funcion en el stack o en las task queue , o micro task?

He aqu铆 un caso real en el cual utilizar generadores es 煤til
En el siguiente ejercicio retomaremos la sucesion de fibonacci, pero esta vez el usuario digitar谩 el indice de la sucesi贸n la cual quiere ver
驴Por qu茅 seria 煤til esto?
Fibonacci puede llegar a ser un numero muy grande, y si se quisiera obtener el siguiente, lo mejor seria tenerlo guardado en el scope de la funcion, tal y como lo hacen los generators.
Pero

  • 驴Y si lo que quiero es n sucesiones anteriores a la actual?
    Para esos casos lo mejor seria resetear el scope y volver a obtener el fibonacci de nuevo

  • 驴Y si el caso es obtener n sucesiones posteriores a la actual?
    En ese caso lo optimo seria retomar el ultimo valor de la sucesi贸n y continuar a partir de este

para poder ejectuar el ejemplo, en la consola:

//DECLARACION DE LA FUNCION
const gen = fibonacci()
//PARA SIGUIENTE INDICE DE SUCESI脫N
gen.next()
//PARA SABER EL RESULTADO DE 'n' INDICE DE LA SUCESI脫N
//con 'n' siendo cualquier numero
gen.next(n)
function*  fibonacci(){
        //DECLARACION DE VARIABLES
        let a = 0;
        let b = 1;
        let nextNumber = 0
        let count = 0
        let n = 0
        while(true){
          // n = AL PARAMETRO QUE INGRESA EL USUARIO 
          n = yield nextNumber
          // SI n = 0 ARRANCA CON LOS VALOREE POR DEFAULT A EXCEPCION DE count
          if(n == 0){
            a = 0;
            b = 1;
            nextNumber = 0
            count = 1
          }
          // SI NO, ENTONCES SI: n < count
          else if(n < count){
            console.log('Arranca la sucesi贸n desde 0');            
            a = 0
            b = 1
            for (let i = 0; i < n; i++) { 
              nextNumber = a + b
              a = b
              b = nextNumber
            }
            count = n
          }
          // SI NO, ENTONCES SI: n>= count
          // AVANZA EL NUMERO DE VECES EN LA SUCESION QUE HAGA FALTA PARA ALCANZAR LA PEDIDA
          // ES DECIR, NO ARRANCAR DESDE 0 LA SUCESION SINO ARRANCAR DESDE DONDE QUEDASTE
          // RECORDAR QUE EL RESULTADO PUEDE LLEGAR A SER UN NUMERO MUY GRANDE
          else if(n >= count){
            console.log(`Avanza ${n - count} sucesiones`);
            for (let i = count; i < n; i++) { 
              nextNumber = a + b
              a = b
              b = nextNumber
            }
            count = n            
          }
          // SI NO, ENTONCES: 
          // EL CASO EN  QUE gen.next()
          else{
            nextNumber = a + b
            a = b
            b = nextNumber
            count ++
          }         
        }
      }

AHORA ES TU TURNO
El codigo puede ser mejorado para prever cualquier error humano en la digitacion, tambien el codigo se puede optimizar mas.
Es tu turno de hacer esto posible.
Buena suerte鈥

Generador de numeros random

    function* numerosRandom(){
        let num;
        while(true){
          yield num = Math.floor((Math.random() *(10-1)+1))
        }
      }

Les comparto 茅sta excelente Kata de c贸digo para practicar generadores: Baum Sweet Sequence

Ten铆a entendido que la serie de Fibonacci empezaba con 1, 1, 2, 3, 5, 8,鈥
Comparto mi modificaci贸n por si a alguien le interesa:

function* fibonacci() {
	let a = 1, b = 1

	while (true) {
		yield a
    let temp = a
    a = b
    b = temp + b
	}
}			

Realmente 煤til, no hab铆a escuchado sobre generadores. pero me recuerda al manejo de Hilos en Sistemas Operativo.

Generators


Los generators son funciones especiales, ya que podemos comenzar su ejecuci贸n, detenerla, el archivo de Js se sigue ejecutando, luego podemos regresar a est谩 funci贸n y terminar de ejecutarla.

Lo interesante es que los generators se recuerdan de su contexto cuando volvemos a retomar su ejecuci贸n.

Para crear un generators utilizamos * despu茅s de poner la palabra reservada function

function* name(params) {

Con la palabra reservada yield el generator se detiene la ejecuci贸n de esa funci贸n y sigue con lo dem谩s. Tambi茅n a trav茅s del yield retornamos el valor que queremos obtener de la funci贸n

     function* simpleGenerator() {
        console.log("Generador Start")
        yield 1
        yield 2
        console.log("Generador End")
      }
const gen = simpleGenerator()

Con el m茅todo .next() ejecutamos el generador.

gen.next()

A trav茅s de .next() tambi茅n podemos pasarle un valor al generador. Tendremos que pasarle true y este va a reestablecer el valor de reset

function* idMakerWithReset() {
        let id = 1
        let reset
        while(true) {
          reset = yield id
          if (reset) {
            id = 1
          } else {
            id += 1
          }
        }
      }

      const idMR = idMakerWithReset()

idMR.next(true)

Esta bueno esto de los generadores!
He cambiado un poco el c贸digo para que salga tambi茅n el 0 y el 1 y un ciclo for para elegir cuantos quieres que salgan.
Lo que no me convence de mi modificaci贸n es que al volver a darle de nuevo una segunda vez la funci贸n en consola, esta se reinicia desde el uno si no pongo dos yield de 0 (el primero lo ignora), a ver si alguien se le ocurre algo para quitar eso y minimizar codigo, quiero aprender a ser mejor entre todos 馃槈

     function* fibonacci(){
        let a = 0;
        let b = 1;
        yield 0;
        while(true){
          const nextNumber = a + b
          a = b;
          b = nextNumber;
          let reset = yield nextNumber;
          if(reset){
            yield 0;
            yield 0;
            a = 0;
            b = 1;
          } 
        }
      }

      const fibo = fibonacci();
      

      const repeticionesFibo = (number) => {
        for(let i = 0; i < number ; i++){
         console.log(fibo.next().value);
        }
        fibo.next(true);
      }

Clase para volar la cabeza. Richard eligi贸 unos muy buenos ejemplos para explicar el tema. Excelente docente

Tengo duda en relacion al Generator de nombre idMakerWithReset. Porque la variable **reset **no cambia su valor al momento de igualarlo al yield?
function* idMakerWithReset() { let id = 1; let reset; while (true) { debugger reset = yield id; if (reset) { id = 1; } else { id = id + 1; } } }

Esto lo explico oscar en el curso de ECMA, muy bueno repasarlo de nuevo

Hola les comparto mi aporte, la serie incluyendo el 1, 1, 2鈥

function* fibo() {
      let s1 = 0
      let s2 = 1
      let nextNumber = 1
      while(true) {
        yield nextNumber
        nextNumber = s1 + s2
        s1 = s2
        s2 = nextNumber
      }
    }

bastante util esta clase

Aqui la clase implementada junto con el DOM鈥

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css?family=Crete+Round&display=swap" rel="stylesheet">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Generadores - Secuencia de Fibonacci</title>

    <style>
        *{
            font-family: 'Crete Round', serif;;
            box-sizing: border-box;
        }

        body{
            background-color: #fffde7;
        }

        header{
            padding-left: 30px;
            display: flex;
            justify-content: space-around;
            align-items: center;
            position: relative;
        }

            .input{
                height: 30px;
                width: 20vw;
                background-color: rgba(255, 255, 255, 0.9);
                padding:15px;
                border-radius: 20px;
                outline: none;
            }
            .button{
                border-radius: 20px;
                display: flex;
                justify-content: center;
                align-items: center;
                outline: none;
                border: none;
                height: 40px;
                width: 100px;
                font-weight: bold;
                letter-spacing: 4px;
                box-shadow: 5px 3px 5px 1px rgba(0, 0, 0, 0.2);
            }
            .button:hover{
                background-color:#f4511e ;
                color: white;
                font-weight: 400;
            }

        main{
            height: calc(100vh - 200px);
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-wrap: wrap;
        }

        p{
            margin: 20px 30px;
            font-size: 2rem;
        }

    </style>
</head>

siento que estoy pasando al lado oscuro de javascript

Amigos si alguien quiere ver un ejemplo de como se puede aplicar los generadores en un caso de html de la vida real les dejo este link de una clase de un curso de Js en youtube
https://www.youtube.com/watch?v=xb9CYd3HgIs&list=PL7rZxwCXrAeyAUrS1R5bUbtQDYMyA85X9&index=58

y el codigo usado para insertar imagenes infinitas con el generador

<!DOCTYPE html>
<html>
<head>
<meta charset=鈥渦tf-8鈥>
<meta name=鈥渧iewport鈥 content=鈥渨idth=device-width鈥>
<title>JS Bin</title>
</head>
<body>
<div id=鈥渃ontainer鈥></div>
<script src=鈥済enerator.js鈥 ></script>
</body>
</html>
// GENERADOR INFINITO ASINCRONO
// Asynchronous Infinite Generator

/* jshint esnext: true */
// noprotect
// https://picsum.photos/200/300
// stream

const container = document.getElementById(鈥榗ontainer鈥);

function delay(n) {
return new Promise((resolve) => {
setTimeout(resolve, n);
});
}

function randomImage() {
return new Promise((resolve, reject) => {
const url = https://picsum.photos/200/300?random=${Math.random()};
const img = document.createElement(鈥榠mg鈥);
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
})
}

function* infiniteGenerator() {
while(true) yield delay(100)
.then(() => {
return randomImage();
});
}

async function consumidor() {
for await (let img of infiniteGenerator()) {
container.appendChild(img);
}
}

consumidor();

script inicial

<html>
<head>
	<title>Generators</title>
</head>
<body>
	<a href="/ejercicios/">Go back</a>	
	<p><em>Abre la consola</em></p>
	<script>
		// Los generadores son funciones de las que se puede salir y volver a entrar.
		// Su contexto (asociaci贸n de variables) ser谩 conservado entre las reentradas.
		// Cada vez que llamamos next, la ejecuci贸n del generador va a continuar hasta el proximo yield
		// Podemos hacer generadores infinitos
		// Cuando llamamos next tambien podemos pasar valores que la funcion recibe
		// Ahora hagamos un ejemplo un poco mas complejo: la secuencia fibonacci
	</script>
</body>

Muy buena esta clase.
Los generadores los podemos utilizar para muchas cosas. Todo depender谩 de lo que queramos hacer.

驴 los generadores son los mismos o trabajan igual que los iteradores de python o hackell?

Excelente Clase no hab铆a escuchado de los generadores y me sorprendi贸 la verdad me ayudo para probar cosas nuevas en un proyecto donde tenia problemas con peticiones a una api, para esperar la respuesta y ahora si ejecutar mi codigo con todos lo datos completos.

Mira ese potencial.jpg

Wow! no conoc铆a los Gnerators, me parece que pueden ser usados para hacer debug de las funciones y evitar usar:

console.log("El programa llego hasta aqu铆"); 

Pero con el 煤ltimo ejemplo parecen tener m谩s profundidad que solo el uso que pens茅.

Toda funci贸n que tenga un * despu茅s de function* es un generador!

A alguien se le ocurre una utilidad en la vida real? Me resulto muy interesante, pero no se me ocurre una utilidad.

los generadores son bastante utiles

Muy bien esta clase primera vez que veo lo de los generators

隆Qu茅 buena clase!

Me podrian explicar en detalle el codigo fibonacci del ejemplo?

function* fibonacci() {
        let a = 1;
        let b = 1;
        while (true) {
          const nextNumber = a + b;
          a = b;
          b = nextNumber;
          yield nextNumber;
        }
      }

En el curso de ECMAScript se mencionan los generadores pero no se ahonda en ellos, aqu铆 se entiende mucho mejor

驴Para que nos servir谩n los generadores?

Yiled significa ceder:

Los generadores se prestan para crear funciones eficientes en memoria.

Los generadores son funciones especiales cuya ejecucion podemos comenzar y detener a mitad de vuelo.

Saludos, compa帽[email protected], este video me ayudo a reforzar https://www.youtube.com/watch?v=oO-D4PsaI1A

Si tienen duda sobre si se pueden usar las funciones flecha como generadores, la respuesta es no. Les comparto un fragmento de la documentaci贸n oficial de las Arrow Functions.

La palabra clave yield no se puede utilizar en el cuerpo de una funci贸n flecha (excepto cuando est谩 permitido dentro de las funciones anidadas dentro de ella). Como consecuencia, las funciones flecha no se pueden utilizar como generadores.

No s茅 si soy solo yo, pero siento que cada cosa que me explican la tengo que estudiar como 20 veces

As铆 hice la secuencia de fibonacci haciendo uso del Swapping.
Ac谩 puede leer mas sobre Swapping :https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

function* fibonacci() {
    let a = 1, b = 1
    while(true){
        yield a;
        [a, b] = [b, a + b]
    }
}

const fibo = fibonacci()

Tambi茅n podemos utilizar destructuraci贸n para comenzar por el 0 + 1鈥

function* fibonacci() {
  let a = 0;
  let b = 1;
  while(true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

Es una de las maneras mas practicas para hacer la serie fibonacci

<code>
function* fibonacci() {
        let a = 1;
        let b = 1;
        while (true) {
          const nextNumber = a + b;
          a= b 
          b = nextNumber;
          yield nextNumber;
        }
      }

De lo mas genial que he visto en JS, me encantan los Generadores.

Una clase divertida, seguimos鈥

Excelente ! No conoc铆a de los generadores, pueden resultar bastante 煤tiles !

La primera vez que v铆 Generators fue en Python, cuando los v铆 me vol贸 la cabeza.
Pueden llegar a ser muy 煤tiles 馃槃

馃く馃く馃く馃く

No conocia sobre generadores, de verdad muy util!

muy interesante, la verdad no la conocia

apenas ejecuta 鈥測ield id鈥 acaba la funci贸n?
osea cuando ponemos yield de nuevo, continua desde el yield donde termin贸 la ultima vez?
osea entra al ciclo while se topa con el yield y termina
cuando ponemos el .nex() retoma desde donde nos quedamos y hace el id =id+1 y otra vez el yield id pero con el nuevo valor y termina la funci贸n.
y asi sucesivamente para todos los .nex() ?

muy bueno eso de los generadores, aun no tengo claro en que se podrian usar, pero seguro se consigue algo

No la tengo toda dominada pero como le dijeron a Yokoi Kenji, tu solo anota y si resulta hacerlo :v

gracias esta genial

Esta clase estuvo muy interesante jamas habia visto esto de generadores ni en js y ni en ning煤n otro lenguaje!

Muy 煤til este tipo de funci贸n

Los generadores se prestan para crear funciones eficientes en memoria, y son funciones especiales cuya ejecucion podemos comenzar y detener a mitad de vuelo solo recordando su scope.

Excelente explicacion del tema de generadores

no imprime los primeros n煤meros 1

Whaaaaaaaaat is this really? Que genial! Esto no me lo sab铆a xD Es pr谩cticamente una funci贸n que puede retornar muchos vaores en cualquier parte y puedes pasarle par谩metros en cualquier parte igual jaja, est谩 genial!

muy interesante, tendr茅 que ir a practicar un poco para digerir el uso de esta herramienta jeje.

Es interesante como ir creciendo en tu entendimiento de la l贸gica de programaci贸n te abre puertas mentales a temas como estos.

Yo era de los que no entend铆a absolutamente nada de este curso, venia del basico de JS y del Practico JS y pens茅 que estaba preparado pero no.
Sin embargo, pese a eso tuve que encontrar el camino para desarrollar mi l贸gica y aqu铆 estoy por segunda vez, y ahora lo entiendo, lo puedo digerir mentalmente entendiendo el porqu茅.

En su momento pens茅 que la metodol贸gia del profe Richard era mala, porque no entend铆a. Me excusaba en que era muy avanzado el tema y que no lo explicaba bien pero, la realidad era que yo no estaba preparado.
Ahora puedo decir que su metodologia no estaba errada ni era mala, era yo el que necesitaba crecer.

Buenisimo, excelente

Muchisimo mejor esta clase sobre generators que la del curso de ECMAscript+

Me parece muy interesante los generadores, pero en el mundo real, en que utilizariamos un generator?

generador

  function* idMaker(){
      let id = crypto.randomUUID();
        while(true){
          yield id;
          id = crypto.randomUUID();
        }
    }
    const gen = idMaker();
gen.next() //  {value: 'e27c5bec-9eb7-4f2a-9aab-f30393f46cbd', done: false}

gen.next() // {value: 'ed4ded37-90a1-4265-a677-e91599881f97', done: false}

Interesante el concepto de generadores, alguien me podria dar mas usos que se le puede dar estas funciones?

Me hab铆a adelantado un poco a la clase y ya hab铆a hecho mi fibonacci 馃槄

Les comparto mi versi贸n.

  function* fibonacciGenerator()聽{
    let a = 0;
    let b = 1;

    while (true) {
      yield a;
      const temp = a;
      a = b;
      b += temp;
    }
  }

  const fibonacci = fibonacciGenerator();

  for (let i = 0; i < 20; i++) {
    console.log(i, fibonacci.next().value);
  }

Por fin entiendo los generadores! brutal clase

Les comparto una funci贸n que hice para que devolviera en un array cada sucesi贸n que se hace, para que puedan ver los 煤ltimos dos n煤meros y verifiquen el resultado.

function* fibonacciPlus()
    {
      let serie = [1, 1];
      let i = 0, j = 1;

      while (true)
      {
        const nextNumber = serie[i] + serie[j];

        i++, j++;
        serie.push(nextNumber);
        yield serie;
      }
    }

me parece excelente el contenido鈥 bastante informacion鈥 muy necesaria muy relevante鈥 ejemplos precisos鈥 toca digerir por tramos鈥 pero bien鈥

Uff esto esta demasiado bueno, se le ve mucha utilidad. 馃

La secuencia fibonacci empieza en 0 xD, es 0 1 1 2 3 5 8 13 y es simplemente porque esta secuencia se genera con la suma de los 2 n煤meros anteriores

Los generadores son funciones especiales. Podemos comenzar su ejecucion y despues detenerla a la mitad. Nuestro programa continua y luego podemos regresar al generador y continuar su ejecucion donde lo dejamos. Cuando los detenemos los generadores recuerdan su contexto.

Para poder declarar un generador necesitamos ponerle un:

function* nombreGenerador(){
	}

Los generadores no son ejecutables, neceistamos declararla en una variable y entonces si podremos ejecutarlas por medio de la variable.

const gen = nombreGenerador();

Los generadores tienen una funcion llamada 鈥榥ext()鈥 es una forma de decirle al generador que continue su ejecucion. Si ejecutamos nos da la salida que le indiquemos y nos entrega un objeto con dos propiedades. Value y Done. Cuando Done sea TRUE es porque el generador acabo su ejecicion. Para poder tener un value definido tenemos que utilizar YIELD que podemos tenerlo para que nuestra funcion no termine y en el objeto ahora nos devuelve un DONE:FALSE porque no a acabado. Ahora al utilizar la funcion 鈥榥ext()鈥 la funcion ahora si terminara.

Cuando usamos Yield podemos regresar un valor y es ahi donde nos devolvera algo en "value鈥 y hacer varios yield para ir parando el programa poco a poco.

Si queremos reiniciar nuestro generador ya que nuestro Yield nos lo retorna. Si utilizamos una condicional podemos mandar un parametro nuevo para poder modificar este programa segun como queramos.

Buenas tardes,

Agradezco su ayuda, 驴Es posible agregar m茅todos a una funci贸n de tipo Generator, como por ejemplo la funci贸n de hasNext()?

Gracias

Muy interesante el uso de los Generadores.

Los generadores son funciones especiales que se declaran como
function nameGen(){}*
Mantienen valores de variables en su scope internos y devuelve una funcion generador que puede ejecutarse y pausarse las veces que sea necesario

/* Trabajando con generadores, que son funciones especiales
las cuales pueden pausar su ejecucion y luego volver a ejecutarse, partiendo
desde el estado en que se paus贸
*/

/* El generador devuelve un objeto, una vez sea ejecutado, con dos propiedades
  value --> almacena el valor que se retorna con yield
  done --> Nos indica que el generador ya ha sido ejecutado por completo
*/
function* generadorSimple(){
  console.log('start');
  // Yield --> seder
  yield 1;
  yield 2;
  yield 3;
  console.log('end');
}

/* Devuelve una funcion, por lo tanto los generadores no son ejecutables directamente*/
const gen = generadorSimple();


// Otro ejemplo

function* idMaker(){
  let id = 1;
  while(true){
    yield id;
    id++;
  }
}

// Pasar un valor al generador

function* idMakerReset(){
  let id = 1;
  let reset;
  while(true){
    /* Al pasarle un valor true al generador, lo que hace en esta linea es
      dejar que yield le asigne ese true a reset, en caso contrario reset va a permanecer
      undefined
    */
    reset = yield id;
    if (reset){
      id = 1;
    } else {
      id++;
    }
  }
}```

驴Cual es la diferencia entre usar un ciclo for pasando la cantidad de elementos que necesitamos generar a utilizar el generator con el while true?

calidad los generadores

Los Generators son funciones regulares que devuelven solo un valor 煤nico (o nada).

Los generadores pueden devolver (鈥測ield鈥) m煤ltiples valores, uno tras otro, bajo demanda. Funcionan muy bien con iterables, lo que permite crear flujos de datos con facilidad.

Para crear un generador, necesitamos una construcci贸n de sintaxis especial: funci贸n *, llamada 鈥渇unci贸n de generador鈥.

Se parece a esto:

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

Las funciones del generador se comportan de manera diferente a las normales. Cuando se llama dicha funci贸n, no ejecuta su c贸digo. En su lugar, devuelve un objeto especial, llamado 鈥渙bjeto generador鈥, para gestionar la ejecuci贸n.

let generator = generateSequence();

let one = generator.next();
let two = generator.next();
let three = generator.next();

Se puede retornar alg煤n valor (No undefined) cuando la funci贸n termina de correr?

Aqu铆 les dejo este ejemplo que hice para la generaci贸n del factorial

function* factorial() {
    let number = 1
    let result = 1

    while (true) {
        result = number * result
        yield result
        number++
    }
}

factorialGenerator = factorial()
factorialGenerator.next().value   // 1
factorialGenerator.next().value   // 2
factorialGenerator.next().value   // 6
factorialGenerator.next().value   // 24
factorialGenerator.next().value   // 120

Los generators me recuerdan mucho al movimiento de las tuercas. Un generator puede ser una tuerca que solo puede moverse por medio de otra. En este caso, un generator ser铆a una funci贸n que solo puede avanzar al ser llamada por otra.

驴Y esto para que sirve? 驴C贸mo lo implementar铆a en una app?

Aqu铆 les dejo un ejemplo con un sorteo para que no se repitan los ganadores, incluye reinicio.

      //sorteo
      function* sorteop() {
        const numOriginals = [1, 2, 3, 4, 5, 6];
        let numbers = [...numOriginals]; // copiamos el array original
        for (let i = 0; i <= numbers.length; ++i) {
          //calculamos un numeo ramdom y le asignamos el valor de un array
          const num = numbers[Math.floor(Math.random() * numbers.length)];
          //console.log(num);
          removeItemFromArr(numbers, num); //eliminamos el valor de larray
          //console.log(numbers);
          //console.log(numOriginals);
          i = 0; // reiniciamos el contador para que vuelva a iniciar
          yield num; // retornarnos el numero
          if (numbers.length == 0) {
            console.log("Se reiniciar谩 el sorteo ");
            //console.log(numOriginals);
            numbers = [...numOriginals]; //copiamos el array original para el reinicio
          }
        }
      }
      
      // una funcion de mozila
      function removeItemFromArr(arr, item) {
        var i = arr.indexOf(item); // obtiene el index del elemento

        if (i !== -1) {
          arr.splice(i, 1); // elimina el elemento del array
        }
      }



En el desarrollo de un juego puede servir para mostrar los dialogos textuales de alg煤n personaje, de forma pausada

馃槑

while (true){
	generator.next()
}

Super genial, muy util los generators

Los generators son funciones especiales que podemos detener su ejecuci贸n a la mitad, seguir con el programa y despu茅s volver al generador y continuar con su ejecuci贸n donde la dejamos.

Cuando se detiene un generator este recuerda el contexto en el que fue detenido (el valor de las variables de su scope).

Declaraci贸n de un generator:

function* simpleGenerator(){
}

Para ejecutar un generator hay que asignarla a una variable para despu茅s llamarlo desde esa variable

const gen = simpleGenerator()
gen.next()

Todos los generators tiene un m茅todo next que hace que contin煤e con su ejecuci贸n.

Para pausar un generator se utiliza el keyword yield. Donde se encuentre este keyword ser谩 donde se pausar谩 la funci贸n y no continuar谩 hasta que se vuelva a ejecutar su m茅todo next. Tambi茅n puede regresar un valor.

function* simpleGenerator(){
	console.log("Hola"); // primer next()
	yield // pausa
	yield 2; // regresa valor
	console.log("Mundo"); // segundo next y final
}

Ejemplo:

function* idMaker(){
	let id = 1;
	while(true){
		yield id;
		id += 1;
	}
}

Tambi茅n se pueden enviar valores al constructor con el m茅todo next.

function* idMarkerWithReset(){
	let id = 1;
	let reset;
	while(true){
		reset = yield id;
		if(reset){
			id = 1;
		} else {
			id += 1;
		}
	}
}

Secuencia Fibonacci con constructores:

function* fibonacci(){
	let a = 1;
	let b = 1;
	while(true){
		yield a + b;
		a = b;
		b = a + b;
	}
}
Buen curso y sin duda uno de los mejores profesores.

Buen video!

creo que estas cosas que tiene javascript son muy 煤tiles en ciertos escenarios.

Excelente tema de los generadores muchas gracias.

Excelente explicaci贸n, no hay que dejar el tema, ya que puede tener una gran utilidad par aplicarse en funciones donde utilizamos loops.

Muy interesante laaplicacion de los genradores

Me causa un poco de ruido que la variable que se definio para actualizar el numero de Fibonacci este declarada como const, alguien podr铆a explicar mejor eso, por que se usa asi y es v谩lido? ya que son constantes que van cambiando su valor 鈥

Este concepto tambi茅n se encuentra en otros lenguajes como Streams (en Dart por ejemplo) 馃槃

Sucesi贸n de Fibonacci
En matem谩ticas, la sucesi贸n o serie de Fibonacci es la siguiente sucesi贸n infinita de n煤meros naturales: La sucesi贸n comienza con los n煤meros 0 y 1;鈥 a partir de estos, 芦cada t茅rmino es la suma de los dos anteriores禄, es la relaci贸n de recurrencia que la define.

Yo me memorise este algoritmo por la escuela

 function* fibunacci(){
            let a=0;
            let b=1;
            let c=1;
            while(true){
                a=b;
                b=c;
                c=a+b;
                yield b;
            }
        }```