Nodejs (2) Capitulo
Nodejs (2) Capitulo
Nodejs (2) Capitulo
Novatec
© Novatec Editora Ltda. 2015.
Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. É proibida a reprodução desta
obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, do autor e da Editora.
ISBN: 978-85-7522-456-4
Histórico de impressões:
Outubro/2015 Primeira edição
Introdução
15
16 Construindo Aplicações com NodeJS
• Todas
http://nodebr.com/instalando-node-js-atraves-do-gerenciador-de-pacotes/
• Mac OS X
http://udgwebdev.com/node-js-para-leigos-instalacao-e-configuracao/
v4.0.0
2.14.2
Arquivo sincrono.js
console.log('1');
t();
console.log('3');
function t() {
console.log('2');
}
Capítulo 1 ■ Introdução 17
Arquivo assincrono.js
console.log('1');
t();
console.log('3');
function t() {
setTimeout(function() {
console.log('2');
}, 10);
}
1 syntactic sugar é uma sintaxe alternativa da linguagem de programação que torna mais
concisa uma declaração.
Capítulo 1 ■ Introdução 19
Closures
O escopo do JavaScript é baseado em funções. O fato de uma função
interna acessar variáveis e parâmetros de um escopo acima do seu
próprio é chamado de closure. Utilizamos closures em JavaScript para
proteger o escopo simulando o que é conhecido como membro privado.
Callback
Um callback é uma função passada como parâmetro para outra função,
para ser executada mais tarde, quando algum processo acabar.
Currying
Esta é uma técnica que consiste em transformar uma função de n
argumentos em outra com menos ou com argumentos mais simples.
Monads
Um design pattern que descreve computação como uma série de etapas.
Trabalha como composição de funções.
Memoization
Memoization (http://addyosmani.com/blog/faster-javascript-memoization/)
é um pattern que serve basicamente para cachear valores já retornados,
fazendo com que a resposta seja mais rápida. Dentre os problemas
que esse pattern resolve, podemos citar cálculos matemáticos recur-
sivos, cache de algum algoritmo ou qualquer problema que possa ser
expressado como chamadas consecutivas a uma mesma função com
uma combinação de argumentos.
Com esse comando, o módulo será baixado para uma pasta chamada
node_modules no mesmo diretório em que você digitou o comando.
Você pode criar uma conta no site www.npmjs.com, caso pretenda publi-
car algum módulo no diretório. É possível também configurar na sua
máquina local os seus dados no npm (https://docs.npmjs.com/cli/config).
Se você estiver em um Linux ou MacOSx, existirá um arquivo .npmrc na
raiz do seu usuário:
$ cat ~/.npmrc
init.author.name=William Bruno
[email protected]
init.author.url=http://wbruno.com.br
ou
$ npm install nvm -g
Sempre que eu iniciar uma linha de exemplo com >, entenda que estamos
dentro do terminal do NodeJS.
> process.version;
'v4.0.0'
> process.versions.v8;
'4.5.103.30'
> process.env.NODE_ENV;
'development'
Comecei simples, como qualquer boa regex. O padrão /rato/ casou com
o texto 'O rato roeu a roupa'. E se mudássemos de rato para gato, teríamos
um false:
> /rato/g.test('O gato roeu a roupa');
false
Se quisermos que a regex case tanto a frase 'O rato roeu a roupa' quanto a
frase 'O gato comeu a roupa', basta alterarmos para:
26 Construindo Aplicações com NodeJS
Ou a função reduce()?
> var arr = [1,2,3,4,5,6], sum = 0;
undefined
> sum = arr.reduce(function(prev, curr){ return prev + curr; });
21
Após o var arr =… aparece um undefined porque essa linha não tem nenhum
retorno ou saída.
Para escrevermos na saída do console, utilizamos a função console.log():
> console.log('Darth Vader');
Darth Vader
undefined
Capítulo 1 ■ Introdução 27
…
global: [Circular],
process:
…
addListener: [Function],
on: [Function],
removeListener: [Function] }
Figura 1.1 – Menu Preferences > Settings – User. Tela do Sublime Text.
Arquivo Preferentes.sublime-settings
{
"color_scheme": "Packages/Color Scheme - Default/Monokai.tmTheme",
"ensure_newline_at_eof_on_save": true,
"file_exclude_patterns":
[
".DS_Store",
"*.min.*"
],
"folder_exclude_patterns":
[
".git",
".tmp",
"coverage",
"node_modules",
"vendor"
],
"font_size": 13,
"highlight_modified_tabs": true,
"ignored_packages":
30 Construindo Aplicações com NodeJS
[
"Vintage"
],
"open_files_in_new_window": false,
"save_on_focus_lost": true,
"scroll_speed": 0,
"side_bar_width": 210,
"smart_indent": true,
"tab_size": 2,
"translate_tabs_to_spaces": true,
"trim_trailing_white_space_on_save": true,
"word_wrap": true
}
1.12.2 EditorConfig.org
O EditorConfig.org (http://editorconfig.org) é um projeto open source que
ajuda equipes de desenvolvedores que utilizam diferentes IDEs e editores
de códigos a manter um estilo consistente no projeto, como por exemplo
utilizar dois espaços para indentar, não permitir espaços desnecessários,
inserir uma nova linha ao final do arquivo etc.
Capítulo 1 ■ Introdução 31
Arquivo .editorconfig
# EditorConfig is awesome: http://EditorConfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
1.14.1 Variáveis
A linguagem JavaScript apresenta seis tipos de dados primitivos:
Destes, apenas null e undefined não têm métodos; todos os outros podem
ser utilizados como objetos.
Para declarar uma nova variável, basta indicar o nome após a palavra re-
servada var, let ou const e atribuir um valor com um símbolo de igualdade.
var creator_name = 'George Lucas';
Nesse exemplo, a função something() teve acesso à variável arr, que foi de-
clarada um escopo acima do seu. E o let que tem escopo por bloco cria
novas referências para cada bloco:
> var out = 'May 25, 1977';
> let out2 = 'Jun 20, 1980';
> if(true) { var out = 'May 25, 1983'; let out2 = 'May 19, 1999'; }
> out;
'May 25, 1983'
> out2
'Jun 20, 1980'
34 Construindo Aplicações com NodeJS
O fato interessante a notar é que a variável out teve o seu valor alterado fora
do bloco do if, enquanto a out2 não. Ela permaneceu com o valor inicial
declarado fora do bloco, enquanto outro espaço de memória foi alocado
para a out2 de dentro do bloco do if. Desse comportamento temos que
let não faz hoisting, enquanto o var faz.
1.14.2 Comentários
A linguagem aceita comentários de linha e de bloco, que são instruções
ignoradas pelo interpretador, que têm como função destacar ou explicar
um trecho de código ao programador que tiver lendo o código-fonte.
> //comentário de linha
>
> /*
comentário de bloco
*/
1.14.3 Funções
Funções no JavaScript podem ser declaradas, atribuídas, passadas por
referência ou retornadas, por isso dizemos que elas são objetos (cidadãos)
de primeira classe.
Existem algumas formas diferentes de declarar uma função, dentre elas,
as duas a seguir são as mais comuns:
> var foo = function() {};
>
> function bar(){}
> (function(){
var princess = 'Leia';
})();
> console.log(princess);
ReferenceError: princess is not defined
A variável princess não existe fora da IIFE, mas a IIFE pode acessar qual-
quer variável que tenha sido declarada fora dela.
Ao invocar:
> sith()
{ DTRACE_NET_SERVER_CONNECTION: [Function],
DTRACE_NET_STREAM_END: [Function],
DTRACE_NET_SOCKET_READ: [Function],
DTRACE_NET_SOCKET_WRITE: [Function],
DTRACE_HTTP_SERVER_REQUEST: [Function],
DTRACE_HTTP_SERVER_RESPONSE: [Function],
DTRACE_HTTP_CLIENT_REQUEST: [Function],
DTRACE_HTTP_CLIENT_RESPONSE: [Function],
global: [Circular],
36 Construindo Aplicações com NodeJS
process:
{ title: 'node',
…
_: [Circular] }
O this agora foi o objeto que passei como argumento da função .bind(). Pode-
ríamos enviar qualquer coisa como argumento (String, Number, Object etc.):
> var lordSith = sith.bind('Darth Bane'); //String
undefined
> lordSith()
[String: 'Darth Bane']
undefined
> var lords = sith.bind(19); //Number
undefined
> lords()
[Number: 19]
undefined
Fica claro que o .bind() retorna uma nova função com um novo escopo.
A função .call() não retorna. Ela executa a função no momento em que
for chamada:
> function sith() { console.log(this); }
undefined
> sith.call({ name: "Darth Maul" });
{ name: 'Darth Maul' }
undefined
Capítulo 1 ■ Introdução 37
Arrow functions
Arrow function ou Fat Arrow function é uma sintaxe alternativa à decla-
ração das funções com a palavra reservada function, além de fazer a
mudança de contexto que o .bind() faz. Por exemplo, a seguinte função
para contar a quantidade de caracteres de cada item do array pode ser
escrita desta forma:
> var studios = ['20th Century Fox', 'Warner Bros.', 'Walt Disney Pictures'];
undefined
38 Construindo Aplicações com NodeJS
1.14.4 Objetos
Podemos declarar novos objetos criados a partir de uma função constru-
tora ou objetos literais, declarados explicitamente.
> function Droid(){}
> var r2d2 = new Droid();
> r2d2
Droid {}
Entendendo o prototype
Todos os objetos no JavaScript são descendentes de Object, e todos os ob-
jetos herdam métodos e propriedades de Object.prototype. Esses métodos
e essas propriedades podem ser sobrescritos. Dessa forma, conseguimos
simular o conceito de herança, além de outras características interessantes
do prototype.
Capítulo 1 ■ Introdução 39
E para usar o prototype para herdar de outros objetos, basta atribuir uma
instância do objeto-base no prototype do objeto onde queremos receber
os métodos e as propriedades:
> function BattleDroid() {}
> BattleDroid.prototype = Object.create(Droid.prototype);
> var b1 = new BattleDroid();
> b1.setLanguages(1);
> b1.getLanguages();
1
Mas, para objetos criados com a notação literal, teremos sempre a mesma
instância, a mesma referência de memória.
> var BattleDroid = {}
> BattleDroid.attack = function() {};
[Function]
> BattleDroid
{ attack: [Function] }
1.14.5 Operações
Os operadores numéricos são +, -, *, / e %, para adição, subtração, multi-
plicação, divisão e resto, respectivamente. Os valores são atribuídos com
um operador de igualdade. O operador + também concatena strings, o
que é um problema, pois podemos tentar somar números com strings e
obter resultados esquisitos.
> 1 + 3 + '2'
'42'
Ainda existem os operadores de bit &, |, ^, ~, <<, >> etc., mas não vou explicá-
-los profundamente aqui. É possível utilizá-los em conjunto, por exemplo,
utilizando dois operadores OU (||), podemos resumir a expressão deste
if ternário:
> var noTry = false ? 'do' : 'do not';
> noTry
'do not'
42 Construindo Aplicações com NodeJS
Em:
> var noTry = false || 'do not';
> noTry;
'do not'
Um bloco switch/case basicamente serve como uma cadeia de if, elseif, else.
Loop for
> var arr = [1,2,3,5,7,11];
> for (var i = 0, max = arr.length; i < max; i++) {
console.log(arr[i]);
}
Capítulo 1 ■ Introdução 43
Loop while
> var arr = [1,2,3,5,7,11];
> var i = 0;
> var max = arr.length;
> while(i < max) {
console.log(arr[i]);
i++;
}
map
> var arr = [1,2,3,5,7,11];
> arr.map(function(x) {
console.log(x);
});
Loop for in
> var arr = [1,2,3,5,7,11];
> for (x in arr) {
console.log(x);
}
1.14.8 Arrays
Arrays são estruturas de dados que lhe permitem colocar uma lista de
valores em uma única variável. Os valores podem ser qualquer tipo de
dado, seja String, Number ou Objeto, ou misto.
Array de Number
> var arr = [];
> arr.push(1);
> arr.push(2);
> arr.push(3);
> arr
[ 1, 2, 3 ]
44 Construindo Aplicações com NodeJS
Array de String
> var arr = [];
> arr.push('a');
> arr.push('b');
> arr.push('c');
> arr
[ 'a', 'b', 'c' ]
Array de objeto
> var arr = [];
> arr.push({ name: 'William' });
> arr.push({ name: 'Bruno' });
> arr
[ { name: 'William' }, { name: 'Bruno' } ]
1.14.9 Promise
Uma promise (https://promisesaplus.com) é uma representação eventual de
uma operação assíncrona, algo que ainda não está completo, mas estará
no futuro. É uma alternativa aos callbacks e nos devolve algumas coisas
básicas da linguagem como try/catch e return. Utilizando corretamente,
conseguimos diminuir o nível de encadeamento, tornando o nosso código
mais legível.
Para declarar uma promise, usamos a função construtora Promise.
> new Promise(function(resolve, reject) {});
Promise { <pending> }
> p1
.then(cb1)
.then(cb2)
.then(cb3)
.catch(cbError);