Advertisement
  1. Code
  2. Node.js

Introdução a Geradores & Koa.js: Parte 1

Scroll to top
Read Time: 9 min
This post is part of a series called Introduction to Generators & Koa.js.
Introduction to Generators & Koa.js: Part 2

Portuguese (Português) translation by Erick Patrick (you can also view the original English article)

O Koa.js é um framework para web, expressivo e de próxima geração, para Node.js, criado pelo pessoal responsável pelos frameworks Express e Connect. O Koa.js lança mão de geradores, que são uma funcionalidade bem recente no JavaScript, e que ainda não chegou às versões estáveis do Node.js. O Koa tem como objetivo lançar mão de geradores para evitar que os desenvolvedores acabem em código espaguete de funções call-backs, diminuindo a ocorrência de erros, tornando-o mais administrável.

Com apenas 550 linhas de código, o Koa é um framework extremamente leve. Ainda assim, o Koa vem com um elegante conjunto de métodos, como os de negociação de conteúdo, redirecionamentos, suporte a proxy, etc., facilitando e acelerando o desenvolvimento, juntamente ao controle granular sobre sua aplicação para Node.

Instalando o Node

Antes de começarmos, você precisará ter a versão 0.11.x do Node, ou mais recente.

Você pode instalar a versão mais recente do Node usando o módulo N:

1
sudo npm install -g n
2
sudo n stable 

Você pode usar outros módulos da comunidade, como o nvm ou construí-lo a partir do código fonte, a escolha é sua. Note que o N também é um módulo da comunidade.

Para executar um código JavaScript que faz uso de geradores, você precisa prover o semáforo (flag) --harmony ao executá-lo.

Por exemplo, para executar o código app.js, digite o seguinte comando:

1
node --harmony app.js

Ou para evitar que tenha de digitar o semáforo todas as vezes, você pode criar um apelido (alias), usando o seguinte comando:

1
alias node="node --harmony"

Agora, para executar suas aplicações que usam geradores, basta digitar:

1
node app.js

Muito bem! Lembre-se que todo o código desse artigo está disponível no GitHub. Sinta-se livre para fazer uma cópia para você e brincar com ele.

Para entender o Koa, primeiro, você tem de entender os geradores, que são a espinha dorsal do framework.

O Que São Geradores?

Com a EcmaScript 6, os geradores finalmente chegaram à terra mágica do JavaScript. Se você já usou geradores em outras linguagens de programação como o Lua, Python, Scheme, Smalltalk, etc., então você ficará feliz de saber que algo muito semelhante foi implementado no JavaScript. 

Os geradores são co-rotinas de primeira classe no JavaScript, isso é, introduzem uma interface de pausa e execução na linguagem. Antes dos geradores, o código inteiro costumava executar do início ao fim, sem uma maneira fácil de parar a execução do código e dar continuidade de onde parou. Agora, sujemos nossas mãos com alguns exemplos.

De acordo com a atual especificação da EcmaScript 6, precisamos usar uma versão diferente de definição de função para criar uma função geradora. Ela se parece com isso:

1
var generator_func = function* () { };

Aqui, a generator_func é só uma função geradora vazia.

O que podemos fazer agora é usar a palavra-chave yield no corpo da função para parar a execução e guardar o estado atual da pilha de execução.

Eis um exemplo simples demonstrando a Soma de uma Progressão Aritmética Infinita:

1
var r = 3;
2
3
function* infinite_ap(a) {
4
 for( ; ; ) {
5
        a = a + r;
6
        yield a;
7
      }
8
}
9
10
var sum = infinite_ap(5);
11
12
console.log(sum.next()); // retorna { value : 8, done : false }

13
console.log(sum.next()); // retorna { value : 11, done: false }

No código acima, começamos criando uma instância de um iterador, chamado de infinite_ap, que inclui o um laço infinito e se executado sob condições normais, pode parar a execução.

Depois, salvamos a instância do iterador na variável sum.

Agora, quando executarmos sum.next(), ela retornará { value: 8, done: false }, significando que ela pausou sua execução quando alcançou a declaração yield retornando value com o valor de 'a' e done com o valor de 'false'.

Enquanto a execução não for finalizada, done continuará retornando 'false'. Assim que a execução estiver finalizada (no caso acima, isso nunca acontece), a função retornará {value: undefined, done: true}.

Eis uma pequena modificação do trecho de código anterior para demosntrar a finalização da execução:

1
var r = 3;
2
3
function* infinite_ap(a) {
4
for( var i = 0; i < 3 ; i++) {
5
       a = a + r ;
6
       yield a;
7
    }
8
}
9
10
var sum = infinite_ap(5);
11
12
console.log(sum.next()); // retorna { value : 8, done : false }
13
console.log(sum.next()); // retorna { value : 11, done: false }
14
console.log(sum.next()); // retorna { value : 14, done: false }
15
console.log(sum.next()); // retorna { value: undefined, done: true } 

Em programas mais complexos, você poderia verificar e usar os valores retornados e o estado done.

Nota: Usar yield sem function* levará a um erro.

Métodos de Geradores Disponíveis

Eis alguns métodos que serão úteis ao lidar com geradores padrão.

Cada um dos métodos abaixo está disponível apenas em uma função geradora e lançará um erro, caso contrário.

next()

Esse método é usado para dar continuidade à execução e os argumentos necessários. Se nada for passado, undefined é passado como o primeiro argumento.

Exemplo: sum.next(5);

throw()

Esse método é usado para lançar um erro ou exceção em qualquer passo. Ele torna a manipulação de erros muito mais fácil. Lançar um erro pode resultar na finalização da execução de um arquivo, caso não seja manipulado em algum lugar. A forma mais simples de manipular erros é usar try-catch. Esse método leva um único argumento que pode ser qualquer coisa.

Exemplo: sum.throw(new Error("Isso é um erro")); 

Delegando o yield

Delegação de geradores é usado para fornecer um gerador a partir de um gerador existente e pode ser usado para compor geradores e, até mesmo, iterar sobre um gerador.

Ao delegar a outro gerador, o gerador atual para de produzir valores para si próprio e começa a esperar pelos valores do gerador delegado até que ele finalize. Uma vez finalizada a delegação do gerador, o gerador original volta a retornar seus próprios valores.

É quase a mesma coisa que usar um laço for-in para iterar sobre o gerador, mas as exceções do gerador delegado são propagadas e lançadas pelo método throw do gerador original, e deveria ser manipulado de acordo. Eis um exemplo:

1
var consoleLogThunk = function(msg) {
2
return function() {
3
        console.log(msg);
4
      }
5
}
6
7
var generator = function*() {
8
    yield consoleLogThunk("Yo");
9
    yield consoleLogThunk("Dawg");
10
    yield consoleLogThunk("!!!");
11
}
12
13
var delegator_function = function* () {
14
    yield consoleLogThunk("I yielded before delegated yield");
15
    yield* generator();
16
    yield consoleLogThunk("I yielded after delegated yield");
17
}
18
19
var k = delegator_function();
20
21
k.next().value();
22
k.next().value();
23
k.next().value();
24
25
console.log(k.next()); // Se você invocar k.next(), será lançado um erro Type, uma vez que o valor é undefined, que não é uma função

26

Agora que você tem sabe um pouco sobre geradores no JavaScript, você pode usá-los para escrever aplicações muito mais claras e precisas, onde você pode criar códigos de I/O, sem bloquear o processo de verdade. 

Passemos para a instalação do Koa e criação de uma aplicação bem simples em Koa.js.

Koa.js:

O Koa é um objeto que contém um vetor de funções geradores de mediador (middlewares), os quais são compostos e executados em pilha a cada requisição.

Instalando Koa

No diretório do seu projeto, execute o comando a seguir.

1
npm install koa --save

Koa será baixado automaticamente e salvo no arquivo package.json, se existir.

Apesar do pequeno do Koa, ela inclui métodos como limpeza de cache, negociação de conteúdo, suporte a proxy, etc., sem qualquer mediador adicionado.

Eis um exemplo de uma aplicação ola-mundo:

1
var koa = require('koa');
2
var app = koa();
3
4
app.use(function *(){
5
this.body = "Olá Mundo !!!";
6
});
7
8
app.listen(3000);

Fluxo de Controle do Koa

Koa também implementa o controle de fluxo de ida e volta. Inicialmente, pode ser difícil de entender, mas, uma vez que conseguir compreender o exemplo abaixo, as coisas ficarão mais claras.

Eis um exemplo de controle de fluxo no Koa:

1
var koa = require('koa')();
2
3
koa.use(function* (next) {
4
// faça algo antes de esperar/passar para a próxima função gerador, que será o primeiro da ida

5
    console.log("A");
6
    yield next;
7
8
    // faça algo quando a execução voltar, esse será o último evento da volta

9
    console.log("B");
10
});
11
12
koa.use(function* (next) {
13
    // faça algo antes de esperar/passar para a próxima função gerador, que será o segundo da ida

14
    console.log("C");
15
16
    yield next;
17
18
    // faça algo quando a execução voltar, esse será o segundo evento da volta

19
    console.log("D");
20
});
21
22
koa.use(function* () { // faça algo antes de esperar/passar para a próxima função gerador, que será a última da ida

23
    console.log("E");
24
    this.body = "hey guys";
25
    console.log("F"); // Primeiro evento da volta (do último para o primeiro)

26
27
});
28
29
koa.listen(3000);

O código acima é bem simples. Note que que nem todos as declarações de console.log são requeridas mas elas ajudarão a clarear o entendimento do fluxo de execução de ida e volta do Koa.js.

Entendendo o Fluxo de Execução do Exemplo

Quando executamos essa aplicação e digitamos o endereço localhost:3000 no navegador, podemos observar que os console.logs no terminal não estão na ordem A-B-C-D-E-F. Nem na ordem A-C-E-B-D-F.

A ordem á A-C-E-F-D-B que demonstra o comportamento de ida e volta dos yields da execução em uma aplicação em Koa.

Talvez tenha notado que a sequência foi impressa duas vezes. Isso é devido à dupla requisição enviada pelo navegador, onde uma serve para buscar o favicon.

Dica: O método koa.use(function) adiciona uma função mediadora à aplicação.

Em Conclusão

E isso é tudo para essa primeira parte deste tutorial sobre geradores no JavaScript e sobre o Koa.js. Você aprendeu sobre a maioria dos pré-requesitos, como o que são geradores, como usá-los, como usar uma submissão delegada e como o controle de fluxo funciona no Koa.js.

Na próxima parte deste tutorial, iremos mais a fundo no Koa e aprenderemos como construir uma aplicação CRUD. Se tiver quaisquer dúvidas ou comentários, sinta-se à vontade de contatar-me ou deixar uma mensagem logo abaixo. 

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.