Front End

1 nov, 2013

Entendendo o Event-loop do Node.js

Publicidade

Trabalhar com funções assíncronas tem ótimos benefícios quando se trata de processamento I/O no servidor. Isso acontece devido ao fato de que uma chamada de I/O é considerada uma tarefa muito custosa para um computador realizar. Tão custosa que chega a ser perceptível para um usuário.

Por exemplo, já percebeu que quando você tenta abrir um arquivo pesado de mais de 1 GB em um editor de texto o sistema operacional trava alguns segundos ou até minutos para abrir? Agora imagine esse problema no contexto de um servidor, que é responsável por abrir esse arquivo para milhares de usuários. Por mais potente que seja o servidor, eles terão os mesmos bloqueios de I/O que serão perceptíveis para o usuário, a diferença é que um servidor estará lidando com milhares usuários requisitando I/O (às vezes milhares requisitando ao mesmo tempo).

É por isso que o Node.js trabalha com assincronismo. Ele permite que você desenvolva um sistema totalmente orientado a eventos, tudo isso graças ao Event-loop.

O Event-loop é um mecanismo interno, que utiliza internamente as bibliotecas:

Elas são nativas da linguagem C e responsáveis por prover a funcionalidade de assíncrono I/O para o Node.js.

Como o Event-loop funciona?

event-loop

Basicamente ele é um loop infinito, que em cada iteração verifica se existem novos eventos em sua fila de eventos. Tais eventos somente aparecem nesSa fila quando são emitidos durante as emissões de eventos na aplicação.

O EventEmitter, é o módulo responsável por emitir eventos, e a maioria das bibliotecas do Node.js herdam desSe módulo suas funcionalidades de emit e listen 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 resultado em um callback. Tal callback geralmente é executado através de uma função de escuta, ou mais conhecida como funções de listen, semanticamente conhecida pelas funções: on(), listen() e outras.

Analisando o clássico “Hello world” que utiliza o módulo http, reparem que ele utiliza dois eventos de escuta. veja o código abaixo:

var http = require('http');

var server = http.createServer(function(request, response){
response.writeHead(200, {"Content-Type": "text/html"});
response.write("<h1>Hello World!</h1>");
response.end();
});

server.listen(3000, function() {
console.log("Servidor rodando!");
});

Nesse clássico exemplo, o Event-loop trabalhará com apenas dois eventos de escuta: http.createServer() e server.listen().

No http.createServer(), o callback desse evento será sempre executado toda vez que um usuário acessar a url desSe servidor. Neste exemplo, é o http://localhost:3000. Na prática, esse evento será executado com maior frequência pelo Event-loop, afinal ele irá colocar na fila cada nova requisição a esse servidor.

Já o server.listen() será executado apenas uma vez pelo Event-loop, pois esse evento ocorre quando o servidor é iniciado. Nesse exemplo, ele é iniciado pela porta 3000.

Programar orientado a eventos vai manter sua aplicação mais robusta e estruturada para lidar com funções que são executadas de forma assíncrona não-bloqueantes.

Para se aprofundar nesse assunto, recomendo que estude o EventEmitter do Node.js; o melhor link é este, e no meu livro tem mais conteúdo prático sobre assincronismo com Node.js. Até a próxima!