JavaScript | Generador

Al igual que los generadores de Python , JavaScript también admite funciones de generador y objetos de generador.
Función de generador: una función de generador se define como una función normal, pero cada vez que necesita generar un valor, lo hace con la palabra clave yield en lugar de return. La declaración de rendimiento suspende la ejecución de la función y devuelve un valor a la persona que llama, pero retiene el estado suficiente para permitir que la función se reanude donde se dejó. Cuando se reanuda, la función continúa la ejecución inmediatamente después de la última ejecución de rendimiento. 
Sintaxis: 
 

// An example of generator function
function* gen(){
     yield 1;
     yield 2;
     ...
     ...
}

Generator-Object: las funciones de generador devuelven un objeto generador. Los objetos generadores se usan llamando al siguiente método en el objeto generador o usando el objeto generador en un bucle «for of» (como se muestra en el programa anterior) 
El objeto Generador es devuelto por una función generadora y se ajusta tanto al iterable protocolo y el protocolo iterador.
 

javascript

<script>
// Generate Function generates three
// different numbers in three calls
function * fun()
{
    yield 10;
    yield 20;
    yield 30;   
}
 
// Calling the Generate Function
var gen = fun();
document.write(gen.next().value);
document.write("<br>");
document.write(gen.next().value);
document.write("<br>");
document.write(gen.next().value);
</script>                   

A continuación se muestra un código de ejemplo para imprimir series infinitas de números naturales usando un generador simple.
 

javascript

<script>// Generate Function generates an
// infinite series of Natural Numbers
function * nextNatural()
{
    var naturalNumber = 1;
 
    // Infinite Generation
    while (true) {
        yield naturalNumber++;
    }
}
 
// Calling the Generate Function
var gen = nextNatural();
 
// Loop to print the first
// 10 Generated number
for (var i = 0; i < 10; i++) {
 
    // Generating Next Number
    document.write(gen.next().value);
 
    // New Line
    document.write("<br>");
}
</script>

Producción 
 

1
2
3
4
5
6
7
8
9
10

A continuación se muestra un ejemplo de cómo regresar manualmente desde un generador
 

javascript

<script>
 
var array = ['a', 'b', 'c'];
function* generator(arr) {
  let i = 0;
  while (i < arr.length) {
    yield arr[i++]
  }
}
 
const it = generator(array);
 
// we can do it.return() to finish the generator
 
</script>

Encontrar rendimiento y sintaxis de rendimiento*
rendimiento: detiene la ejecución del generador y devuelve el valor de la expresión que se escribe después de la palabra clave de rendimiento.
yield*: itera sobre el operando y devuelve cada valor hasta que done sea verdadero.
 

javascript

<script>
 
const arr = ['a', 'b', 'c'];
 
function* generator() {
  yield 1;
  yield* arr;
  yield 2;
}
 
for (let value of generator()) {
  document.write(value);
  document.write("<br>");
}
 
</script>

Producción 
 

1
a
b
c
2

Otro método para crear iterables.
 

javascript

<script>
 
var createOwnIterable = {
  *[Symbol.iterator]() {
    yield 'a';
    yield 'b';
    yield 'c';
  }
}
 
for (let value of createOwnIterable) {
  document.write(value);
  document.write("<br>");
}
 
<script>

Producción 
 

a
b
c

Retorno de una función generadora 
 

javascript

<script>
 
function* generator() {
  yield 'a';
  return 'result';
  yield 'b';
}
 
var it = generator();
document.write(JSON.stringify(it.next()));
// {value: "a", done: false}
document.write(JSON.stringify(it.next()));
// {value: "result", done: true}
 
</script>

Cómo lanzar una excepción desde el generador
 

javascript

<script>
 
function* generator() {
  throw new Error('Error Occurred');
}
 
const it = generator();
it.next();
// Uncaught Error: Error Occurred
 
</script>

Llamar a un generador desde otro generador
 

javascript

<script>
 
function* firstGenerator() {
  yield 2;
  yield 3;
}
 
function* secondGenerator() {
  yield 1;
  yield* firstGenerator();
  yield 4;
}
 
 
for (let value of secondGenerator()) {
  document.write(value)
  document.write("<br>");
}
 
</script>

Producción 
 

1
2
3
4

Limitación de generadores  
que no puede producir dentro de una devolución de llamada en generadores 
 

javascript

<script>
 
function* generator() {
  ['a', 'b', 'c'].forEach(value => yield value) // This will give syntax error
}
 
</script>

Uso de generadores asíncronos (para llamadas api)
 

javascript

<script>
 
const firstPromise = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(1), 5000)
  })
}
 
const secondPromise = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(2), 3000)
  })
}
 
async function* generator() {
  const firstPromiseResult = await firstPromise();
  yield firstPromiseResult;
  const secondPromiseResult = await secondPromise();
  yield secondPromiseResult;
}
 
var it = generator();
for await(let value of it){
  document.write(value);
  document.write("<br>");
}
 
</script>

Producción 
 

(after 5 seconds)
1 
(after 3 seconds)
2

Ventajas de los generadores: 
Son eficientes en memoria ya que tiene lugar una evaluación perezosa, es decir, retrasa la evaluación de una expresión hasta que se necesita su valor.
caso de uso (generadores) 
 

  • generadores de escritura en redux-saga
  • async-await (Implementado con promesa y generadores)

Navegador compatible:

  • Google Chrome 39 y superior
  • Microsoft Edge 13 y superior
  • Firefox 26 y superior
  • Ópera 26 y superior
  • Safari 10 y superior

Publicación traducida automáticamente

Artículo escrito por ShivamKD y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *