Node.js permite que programas autônomos escritos em JavaScript possam usar eventos I/O como o EventMachine ou Twisted do Phyton, Dispatch Sources do GDC (Grand Central Dispatch), filas e muitos outros sistemas similares.
Esta apresentação discute a implementação e ideias de design por trás do Node.js (link em PDF em inglês). Essencialmente, o Node.js permite escrever código como este abaixo (retirado do PDF):
http.createServer( function (req,res) { res.sendHeader(200, {"Content-Type": "text/plain"}); res.sendBody("Hello\r\n"); res.sendBody("World\r\n"); res.finish(); }).listen(8000);
A chamada createServer
estabelece ao sistema para ouvir na porta 80; quando uma conexão chega, a função anônima passada é invocada. Não há necessidade de invocar threads manualmente ou despachar os pedidos recebidos, o Node.js cuida de tudo isso.
Este é apenas um exemplo, de muitos outros I/O, tanto quanto a leitura como a escrita, podem ainda ser manipuladas com callbacks e eventos. Leituras assíncronas do stdin
também são possíveis.
O conceito de evento é utilizado em todas APIs do Node.js. Muitos sistemas diferentes permitem registrar ouvintes para todos os tipos de eventos, simplesmente usando o método addListener
Por exemplo, o objeto global process
, permite ouvir sinais do OS com este código (também retirado do PDF):
process.addListener("SIGINT", function () ( puts("good bye"); process.exit(0) ) );
Outras bibliotecas retornam objetos Promise que emitem um desses eventos: "success", "error" e "cancel". Um exemplo dos documentos da API do Node.js:
var posix = require("posix"), sys = require("sys"); var promise = posix.unlink("/tmp/hello"); promise.addCallback(function () { sys.puts("successfully deleted /tmp/hello"); ));
A chamada promise.addCallback
registra um ouvinte que é chamado quando o Promise emitir o evento "success" - neste exemplo, quando a chamada da API for concluída com êxito. Algo semelhante pode ser alcançado pelas chamadas wait
ou timeout
no objeto Promise, que bloqueia por tempo indeterminado ou até o timeout ser disparado.
Com o conceito do Promise, Node.js pode executar chamadas bloqueadoras sem efetivamente bloquear o código JavaScript. Estas chamadas são realizadas em background através de threads que, depois que estiverem completas, dispara os eventos do Promise.
Para atingir seus objetivos, o Node.js usa o Google V8 misturado com algumas bibliotecas:
- libev implementa eventos de repetição e abstrai o básico da tecnologia específica usada (como
select epoll
etc) - libeio usa um conjunto de threads para executar chamadas bloqueadoras em background. O udns ajuda nessa questão implementando uma biblioteca non-blocking de resolução de DNS (resolução de DNS está frequentemente disponível apenas como uma chamada bloqueadora no Sistema Operacional).
- implementações de protocolos tipo http-parser
Existem já algumas bibliotecas construídas sobre o Node.js, conectando com bases de dados, protocolos como Bert-RPC e muitas outras.
Suporte para API do HTML5 está incluso; Desenvolvedores Web conseguem habilitar o javascript pra realizar novas funções que executam tarefas. Ao contrário de segmentos de memória compartilhada, Desenvolvedores Web não veem o segmento de memória dos outros (ou as que ele mesmo criou), a comunicação ocorre apenas via troca de mensagem, o que faz ficar um pouco parecido com processos Erlang.
Node.js navega com um executável que roda arquivos Javascript, assim como uma shell (REPL) que torna mais fácil os testes do código JavaScript.
Para mais informações, Simon Willison possui um artigo que cobre o Node.js, o artigo também fornece alguns exemplos usando a biblioteca Node.js, por exemplo, acessando Redis ou criando aplicativos web.
Node.js permite usar o Javascript mais do que uma linguagem de script GUI. Ele herda um problema do Javascript: a falta de uma biblioteca Javascript padrão. Node.js vem com bibliotecas, e as mencionadas bibliotecas de terceiros certamente ajudarão, mas ainda não está perto das funcionalidades encontradas nas bibliotecas padrão do Java e do Ruby. A crescente popularidade do JavaScript para escrever aplicações cliente, possibilita propósitos de uso mais geral e bibliotecas baseadas fora do browser irão aparecer.
Você consideraria o uso do Node.js? Você usaria ele para o que?