Funções geradoras


Funções geradoras (ou Generator Function) são um recurso avançado do JavaScript que permitem a criação de iteradores de maneira controlada. Elas são capazes de pausar a execução do código em pontos específicos, permitindo a entrega de valores sob demanda, o que é conhecido como “lazy evaluation” (avaliação tardia/preguiçosa). A principal diferença em relação às funções comuns é a presença do operador yield, que indica onde a execução da função deve ser pausada.

Sintaxe

function* nomeDaFuncao() {
  // Código ...
  yield [valor 1];
 
  // Código ...
  yield [valor 2];
 
  // Código ...
  yield [valor 3];
}
  • yield: Representa o valor retornado para cada invocação da função. A execução é pausada até que a função seja chamada novamente.

  • next(): Método utilizado para obter o valor do próximo yield da função geradora.

Exemplos

Função geradora básica

function* geradora1() {
  yield "Valor 1";
  yield "Valor 2";
  yield "Valor 3";
}
 
const g1 = geradora1();
 
console.log(g1); // Object [Generator] {}
 
console.log(g1.next()); // { value: 'Valor 1', done: false }
 
console.log(g1.next().value); // Valor 2
console.log(g1.next().value); // Valor 3
function* geradora1() {
  yield "Valor 1";
  yield "Valor 2";
  yield "Valor 3";
}
 
const g1 = geradora1();
 
for (let valor of g1) {
  console.log(valor);
}
 
/*
Valor 1
Valor 2
Valor 3
*/

Gerador infinito

function* geradoraInfinita() {
  let i = 0;
 
  while (true) {
    yield i;
    i++;
  }
}
 
const geradora = geradoraInfinita();
 
console.log(geradora.next().value);
console.log(geradora.next().value);
console.log(geradora.next().value);
console.log(geradora.next().value);
 
/*
0
1
2
3
*/

Gerador para delegar tarefas para outras funções geradoras

function* geradoraDelegar() {
  yield 0;
  yield 1;
  yield 2;
}
 
function* geradora1() {
  yield* geradoraDelegar();
  yield 3;
  yield 4;
  yield 5;
}
 
const g1 = geradora1();
 
for (let valor of g1) {
  console.log(valor);
}
 
/*
0
1
2
3
4
5
*/

Operador yield retornando uma Função

function* geradora() {
  yield function () {
    console.log("Vim do yield 1");
  };
 
  yield function () {
    console.log("Vim do yield 2");
  };
}
 
const g = geradora();
 
const func1 = g.next().value;
const func2 = g.next().value;
 
func1();
func2();
 
/*
Vim do yield 1
Vim do yield 2
*/

Declaração return em funções geradoras

function* geradora() {
  yield function () {
    console.log("Vim do yield 1");
  };
 
  return function () {
    console.log("Vim do return");
  };
 
  // Código inalcançável:
  // yield function() {
  //   console.log("Vim do yield 2");
  // }
}
 
const g = geradora();
 
const func1 = g.next().value;
const func2 = g.next().value;
 
func1();
func2();
 
/*
Vim do yield 1
Vim do return
*/

Referências