Javascript JavaScript Generators e onde usá-los

Veja como e onde podemos aproveitar os Generators no JavaScript para melhorar o nosso código.

Akira Hanashiro 14 de junho de 2017

Olá, Web Developers!

Anteriormente escrevi aqui sobre os Generators. Agora vamos ver duas das principais situações onde eles vêm sendo bastante utilizados.

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

Iterators

Iterator é um objeto que nos fornece o método next() para acessar cada um dos valores que ele contém. Um Array e uma String já possuem Iterators por natureza. Por exemplo: O Iterator da String "TreinaWeb" nos retornaria uma letra por vez a cada execução do método next().

Iterators são criados com o Symbol @@iterator, mas também podemos usar Generators para criá-los de uma maneira bem mais simples:

function* fibonacci(){
    var n1 = 1,
        n2 = 1;
    while(true){
        var current = n2;
        n2 = n1;
        n1 += current;
        yield current;
    }
}

var fib = fibonacci();
console.log(fib.next()); // 1
console.log(fib.next()); // 1
console.log(fib.next()); // 2
console.log(fib.next()); // 3
console.log(fib.next()); // 5

Fluxo Assíncrono

Já que o Generator para a execução e nos dá a possibilidade escolhermos quando continuar, ele pode ser de grande ajuda em códigos assíncronos. Muitos desenvolvedores estão utilizando-o para fazer com que códigos com Promises fiquem mais parecidos visualmente com um código síncrono.

Vamos imaginar a seguinte situação:

function func1(number){
    return new Promise(resolve =>{
        setTimeout(() => resolve(77 + number) , 1000)
    })
}

function func2(number){
    return new Promise(resolve =>{
        setTimeout(() => resolve(22 + number) , 1000)
    })
}

function func3(number){
    return new Promise(resolve =>{
        setTimeout(() => resolve(14 * number) , 1000)
    })
}

// Usando as funções
func1(4)
   .then(number => {
        console.log('Hello');
        return func2(number);
   })
   .then(number => {
        console.log('World');
        return func3(number);
   })
   .then(result => console.log(result))

Fizemos um exemplo bem genérico, onde temos três funções assíncronas, e entre as respostas delas, fazemos uma operação com console.log().

Você pode imaginar isso como, por exemplo, fazer requisição a um servidor, processar os dados, fazer outra requisição com os dados processados, receber os dados e finalmente, exibí-los na tela.

Veja como podemos deixar com um visual mais parecido com código síncrono, usando a biblioteca co:

var co = require('co');

// As funções de antes
co(function* (){
  var a = yield func1(4);

  console.log('Hello');
  var b = yield func2(a);

  console.log('World');
  var c = yield func3(b);

  console.log(c)
})

Criamos uma função anônima como Generator e a passamos para a função co da biblioteca que importamos. A cada execução de uma Promise, passamos o yield junto. Na linha seguinte podemos continuar escrevendo normalmente, como um código síncrono comum. Nada de ficar encadeando then.

Esse comportamento pode ser feito com o Async/Await. A maioria dos navegadores modernos já estão dando suporte e o Node.js já suporta desde a versão 7.

Concluindo

Os Generators já possuem um bom suporte nos navegadores modernos. Eles nos possibilitam trabalhar de novas formas, e cada vez mais a forma como escrevemos JavaScript vem sendo mudada.

Como sempre, em programação podemos fazer a mesma coisa de várias maneiras, e o Generator é uma poderosa adição ao nosso arsenal. É uma boa ferramenta para trabalharmos com código assíncrono.

Caso você esteja interessado em saber mais sobre código assíncrono, programação reativa e funcional, veja o nosso curso de RxJS.

RxJS - Programação reativa
Curso de RxJS - Programação reativa
CONHEÇA O CURSO
Deixe seu comentário

Conheça o autor desse artigo

  • Foto Autor Akira Hanashiro
    Akira Hanashiro

    Graduado em Análise e Desenvolvimento de Sistemas, Pós-graduado em Projetos e Desenvolvimento de Aplicações Web e MBA em Machine Learning. Especializado em Front End e curte desenvolvimento de jogos.

    Posts desse Autor

Artigos relacionados