Descondificando CC

Geradores em JavaScript (Controlando funções)

August 26, 2019

Javascript
Intermediário

Os geradores são funções cuja execução pode ser interrompida, reconduzida ou anulada.

function main() {
  let quatro = 2 + 2;
  let seis = quatro + 2;
  return seis;
}

Observe a função acima, ela é executada na sua totalidade sem nenhuma interrupção, pois funções normais não permitem-nos controlar o que elas fazem dentro de seus blocos.

Digamos que aconteça um erro ao tentarmos obter o resultado do cálculo 2 + 2, se não aplicarmos nenhum tratamento de erro dentro do bloco desta função, neste caso, nada podemos fazer para evitar que o erro se propague. É aí que aplicamos as funções geradoras.

Para criarmos uma função geradora, o que temos de fazer é simplesmente adicionar um asteristico(*) logo após a palavra-chave function.

Exemplo:

function* main() {
  let quatro, seis;
  yield (quatro = 2 + 2);
  yield (seis = quatro + 2);
}

const resultado = main();

Vamos lá analisar esta função detalhadamente.

Como podemos ver, o primeiro passo foi adicionar o * logo após a palavra-chave function e em seguida declaramos as nossas varíaveis quatro e seis. Depois da declaração das varíaveis passamos então à fase do cálculo.

Antes de efectuarmos cada cálculo, usamos a palavra-chave yield. O que significa yield ?

Basicamente yield retorna o resultado da expressão em que ela for aplicada quando charmarmos o iterador next().

Ao invocarmos uma função geradora, o seu conteúdo não é executado imediatamente. Nos é retornado um objecto do tipo iterator. A execução é somente feita quando chamamos o método next() que ela nos retorna um objecto com duas propriedades.

  • value: o valor retornado pelo yield.
  • done: um booleano indicando se a função foi executada na sua totalidade.

Executando a função

Como descrito antes, após a invocação de uma função geradora, a sua execução so é feita quando chamamos o método next().

Exemplo:

resultado.next(); // {value: 4, done: false}
resultado.next(); // {value: 6, done: false}
resultado.next(); // {value: undefined, done: true}

Desta forma então, podemos finalmente controlar cada passo da execução da nossa função. Caso algo aconteça ao longo da primeira chamada do método next() podemos parar a execução da função.