Geradores

Frontend SELF PT
Nível 45 , Lição 1
Disponível

2.1 Sintaxe de geradores

Os geradores em JavaScript são funções especiais que permitem controlar a execução do código. Eles podem pausar sua execução e retomá-la mais tarde, tornando-os uma ferramenta poderosa para trabalhar com código assíncrono, iteradores e outras tarefas complexas.

Os geradores são definidos usando a função function* (repara na estrelinha). Dentro do gerador, utilizamos o operador yield para pausar a execução e retornar um valor.

Declaração de um gerador:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        yield 3;
      }
    
  

Criando um objeto gerador

Chamar o gerador não executa seu corpo imediatamente. Em vez disso, ele retorna um objeto gerador, que pode ser usado para iterar sobre os valores:

JavaScript
    
      const gen = generatorFunction();
    
  

2.2 Usando geradores

Método next()

O método next() é usado para retomar a execução do gerador até o próximo operador yield. Ele retorna um objeto com duas propriedades:

  • value: o valor passado pelo operador yield
  • done: valor booleano indicando se o gerador está concluído (true) ou não (false)

Exemplo de uso do método next():

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        yield 3;
      }

      const gen = generatorFunction();

      console.log(gen.next()); // { value: 1, done: false }
      console.log(gen.next()); // { value: 2, done: false }
      console.log(gen.next()); // { value: 3, done: false }
      console.log(gen.next()); // { value: undefined, done: true }
    
  

Iteração sobre um gerador

Os geradores podem ser usados com o loop for...of para iterar sobre os valores.

Exemplo de iteração sobre um gerador:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        yield 3;
      }

      const gen = generatorFunction();

      for (const value of gen) {
        console.log(value);
      }

      // Saída: 1
      // Saída: 2
      // Saída: 3
    
  

Exemplo de retorno de valores

Os geradores podem retornar um valor usando o operador return:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        return 3;
        yield 4; // Este yield nunca será executado
      }

      const gen = generatorFunction();

      console.log(gen.next()); // { value: 1, done: false }
      console.log(gen.next()); // { value: 2, done: false }
      console.log(gen.next()); // { value: 3, done: true }
      console.log(gen.next()); // { value: undefined, done: true }
    
  

2.3 Uso avançado de geradores

Interação com um gerador

O método next() pode receber um argumento, que é passado para o gerador e pode ser usado dentro dele.

Exemplo de passagem de valores para um gerador:

JavaScript
    
      function* generatorFunction() {
        const value1 = yield 1;
        const value2 = yield value1 + 2;
        yield value2 + 3;
      }

      const gen = generatorFunction();

      console.log(gen.next()); // { value: 1, done: false }
      console.log(gen.next(10)); // { value: 12, done: false }
      console.log(gen.next(20)); // { value: 23, done: false }
      console.log(gen.next()); // { value: undefined, done: true }
    
  

Tratamento de erros

Os geradores permitem tratar erros usando o bloco try...catch.

Exemplo de tratamento de erros:

JavaScript
    
      function* generatorFunction() {
        try {
          yield 1;
          yield 2;
        } catch (error) {
          console.log('Erro capturado:', error);
        }
      }

      const gen = generatorFunction();

      console.log(gen.next()); // { value: 1, done: false }
      console.log(gen.throw(new Error('Algo deu errado'))); // Erro capturado: Error: Algo deu errado

      // { value: undefined, done: true }
    
  

Exemplo de gerador para criar sequência infinita

Os geradores podem ser usados para criar sequências infinitas de valores:

JavaScript
    
      function* infiniteSequence() {
        let i = 0;
        while (true) {
          yield i++;
        }
      }

      const gen = infiniteSequence();

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

      // e assim por diante
    
  

2.4 Exemplos de uso prático

Exemplo 1: Gerador para iterar sobre um objeto

JavaScript
    
      function* objectEntries(obj) {
        const keys = Object.keys(obj);
        for (const key of keys) {
          yield [key, obj[key]];
        }
      }

      const obj = { a: 1, b: 2, c: 3 };
      const gen = objectEntries(obj);

      for (const [key, value] of gen) {
        console.log(`${key}: ${value}`);
      }

      // Saída:
      // a: 1
      // b: 2
      // c: 3
    
  

Exemplo 2: Gerador para implementar um iterador simples

JavaScript
    
      const myIterable = {
        *[Symbol.iterator]() {
          yield 1;
          yield 2;
          yield 3;
        }
      };

      for (const value of myIterable) {
        console.log(value);
      }

      // Saída: 1
      // Saída: 2
      // Saída: 3
    
  

Os geradores em JavaScript são uma ferramenta poderosa para controlar a execução do código, criar iteradores e trabalhar com operações assíncronas. Compreender a sintaxe e o uso de geradores ajuda a criar um código mais flexível e legível, especialmente ao lidar com sequências de dados e tarefas assíncronas.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION