responsável por emitir eventos e a maioria das bibliotecas do Node.js herdam deste
módulo suas funcionalidades de eventos. Quando um determinado código emite
um evento, o mesmo é enviado para a fila de eventos para que o Event-loop execute-o, e em seguida retorne seu callback. Tal callback pode ser executado através de uma
função de escuta, semanticamente conhecida pelo nome: on().
Programar orientado a eventos vai manter sua aplicação mais robusta e es-
truturada para lidar com eventos que são executados de forma assíncrona não-
bloqueantes. Para conhecer mais sobre as funcionalidades do EventEmitter
acesse sua documentação:
http://nodejs.org/api/events.html
27
3.4. Evitando Callbacks Hell
Casa do Código
3.4
Evitando Callbacks Hell
De fato, vimos o quanto é vantajoso e performático trabalhar de forma assíncrona,
porém em certos momentos, inevitavelmente implementaremos diversas funções as-
síncronas, que serão encadeadas uma na outra através das suas funções callback.
No código a seguir apresentarei um exemplo desse caso. Crie um arquivo chamado
callback_hell.js, implemente e execute o código abaixo:
var fs = require('fs');
fs.readdir(__dirname, function(erro, contents) {
if (erro) { throw erro; }
contents.forEach(function(content) {
var path = './' + content;
fs.stat(path, function(erro, stat) {
if (erro) { throw erro; }
if (stat.isFile()) {
console.log('%s %d bytes', content, stat.size);
}
});
});
});
Reparem na quantidade de callbacks encadeados que existem em nosso código.
Detalhe: ele apenas faz uma simples leitura dos arquivos de seu diretório e imprime
na tela seu nome e tamanho em bytes. Um pequena tarefa como essa deveria ter
menos encadeamentos, concorda? Agora, imagine como seria a organização disso
para realizar tarefas mas complexas? Praticamente o seu código seria um caos e total-
mente difícil de fazer manutenções. Por ser assíncrono, você perde o controle do que
está executando em troca de ganhos com performance, porém, um detalhe impor-
tante sobre assincronismo é que na maioria dos casos os callbacks bem elaborados
possuem como parâmetro uma variável de erro. Verifique nas documentações sobre
sua existência e sempre faça o tratamento deles na execução do seu callback: if
(erro) { throw erro; }, isso vai impedir a continuação da execução aleatória
quando for identificado um erro.
Uma boa prática de código Javascript é criar funções que expressem seu ob-
jetivo e de forma isoladas, salvando em variável e passando-as como callback.
Ao invés de criar funções anônimas, por exemplo, crie um arquivo chamado
callback_heaven.js com o código abaixo:
28
Casa do Código
Capítulo 3. Por que o assíncrono?
var fs = require('fs');
var lerDiretorio = function() {
fs.readdir(__dirname, function(erro, diretorio) {
if (erro) return erro;
diretorio.forEach(function(arquivo) {
ler(arquivo);
});
});
};
var ler = function(arquivo) {
var path = './' + arquivo;
fs.stat(path, function(erro, stat) {
if (erro) return erro;
if (stat.isFile()) {
console.log('%s %d bytes', arquivo, stat.size);
}
});
};
lerDiretorio();
Veja o quanto melhorou a legibilidade do seu código. Dessa forma deixamos
mais semântico e legível o nome das funções e diminuímos o número de encade-
amentos das funções de callback. A boa prática é ter o bom senso de manter no
máximo até dois encadeamentos de callbacks. Ao passar disso significa que está na
hora de criar uma função externa para ser passada como parâmetro nos callbacks,
em vez de continuar criando um callback hell em seu código.
29
Capítulo 4
Iniciando com o Express
4.1
Por que utilizá-lo?
Programar utilizando apenas a API HTTP nativa é muito trabalhoso! Conforme
surgem necessidades de implementar novas funcionalidades, códigos gigantescos se-
riam acrescentados, aumentando a complexidade do projeto e dificultando
futuras
manutenções.
Foi a partir desse problema que surgiu um framework muito popular, que se
chama Express. Ele é um módulo para desenvolvimento de aplicações web de grande
escala. Sua filosofia de trabalho foi inspirada pelo framework Sinatra da linguagem
Ruby. O site oficial do projeto é: (http://expressjs.com) .
4.2. Instalação e configuração
Casa do Código
Figura 4.1: Framework Express.
Ele possui as seguintes características:
MVR (Model-View-Routes);
MVC (Model-View-Controller);
Roteamento de urls via callbacks;
Middleware;
Interface RESTFul;
Suporte a File Uploads;
Configuração baseado em variáveis de ambiente;
Suporte a helpers dinâmicos;
Integração com Template Engines;
Integração com SQL e NoSQL;
4.2
Instalação e configuração
Sua instalação é muito simples e há algumas opções de configurações para começar
um projeto. Para aproveitar todos os seus recursos, recomendo que instale-o em
modo global:
npm install -g express
32
Casa do Código
Capítulo 4. Iniciando com o Express
Feito isso, será necessário fechar e abrir seu terminal para habilitar o comando
express, que é um CLI (Command Line Interface) do framework. Ele permite gerar