JavaScript Assíncrono com Generators

Olá, Web Developers!

Você já usou Generators? Possuímos a mesma coisa em linguagens como Ruby, por exemplo. Para quem nunca viu, esse nome pode assustar no começo. Mas os Generators são apenas funções. A diferença é que podemos pausar essa função em uma determinada linha e depois mandá-la continuar de onde parou.

Essa é uma funcionalidade que veio no ES2015 para nos auxiliar no desenvolvimento de código assíncrono. Vejamos um exemplo simples de Generator:

function* myCounter(){
    var i = 0;
    while(true){
        yield i++;
    }
}

var counter = myCounter();

A primeira diferença que notamos com uma função comum é o “*” depois de “function”. Isso indica que essa função é um Generator. Dentro da função criamos um looping infinito que incrementa uma variável.

Dentro do looping colocamos o comando yield. Pense nesse comando como um return. O yield retornará o valor passado para ele e irá pausar a função. Note que eu disse que a função foi pausada, e não finalizada.

Depois, executamos a nossa função, que é um Generator, e guardamos o seu retorno na variável counter. Porém, counter não irá receber o valor que passamos para o yield. Receberemos um objeto que nos informa o valor e se o Generator foi finalizado.

Para pegar o valor que passamos no yield, basta executar a função next().

var counterValue = counter.next();

Múltiplos yields

Podemos ter vários yield em uma função, como:

function* myGenerator(){
    yield 5;
    console.log("we’re back!");
    yield 10;
}

Ao executar o Generator, a função irá parar no primeiro yield. Ao executar next() pela primeira vez, obteremos o valor 5. Ao executar next() pela segunda vez, a mensagem “we’re back!” será impressa e receberemos o valor 10.

Lista de retornos

Ao invés de um looping para ficar exibindo itens de um Array, podemos mandar o Generator retornar um valor por vez:

function* myGenerator1(){
    yield [1,2,3,4,5];
}

function* myGenerator2(){
    yield* [1,2,3,4,5];
}

No myGenerator1, ao executar o next() receberemos um array. Mas no myGenerator2, receberemos primeiro o 1, depois o 2, depois o 3, etc, conforme formos executando o next(). Para esse comportamento, basta colocar o * junto ao comando yield.

Finalizando

Os Generators já possuem um bom suporte nos navegadores modernos. Caso haja necessidade de dar suporte a navegadores mais antigos, você pode usar o Babel para transformar o seu código em ES5.

É 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:

Não conhecia o Generators? O que achou? Já conhecia ou precisou em algum projeto?

Compartilhe com a gente nos comentários!