fbpx

Node.js entendendo event loop e as partes que o compõem

Desenvolvimento

História

Node.js foi criado em 2009 por Ryan Dahl, inspirado pela barra de progresso de upload de arquivos do Flickr, onde ele percebeu que o navegador não sabia o quanto do arquivo foi carregado e tinha que consultar um servidor web para ter essa informação.

Node.js é um ambiente de execução JavaScript Server-side e open source, usando de uma combinação do Google V8, Event loop e Single thread, API assincronas e I/O não bloqueante, o projeto foi apresentado pela primeira vez no JSConf europeu de 2009.

O Google V8

O V8 é uma engine criada pela Google, open source e escrita em c++, usada no Google Chrome e também pelo runtime do Node.js, ela foi projetada para aumentar a performance de execução do JavaScript nos navegadores web.

O JavaScript sendo uma linguagem interpretada, tem uma performance menor do que uma linguagem compilada, o V8 foi criado pensando nesse problema da linguagem, ao invés de usar um interpretador, ele compila o código JavaScript para código de máquina, executa, manipula alocação de memória e faz trabalho de garbage collector.

Single thread

O Node.js veio com proposta de uma única thread, onde apenas uma thread cuida das requisições, cada requisição é tratada como um evento. Diferente de outras linguagens como PHP, Java e Ruby, que são multi thread, onde toda requisição recebida é criada uma nova thread, o que muitas das vezes acaba consumindo recursos computacionais de forma desnecessária. 

Esse modelo pode parecer estranho à primeira vista, pois sempre ouvimos que ter algo multi thread é mais performático, porém mesmo o Node.js sendo single thread, conseguimos tratar requisições de forma concorrente. Utilizando de chamadas I/O não bloqueantes e API assíncronas, considerada uma forte característica dentro do Node.js, não bloquear a execução de recursos facilita a execução paralela e aproveita melhor os recursos computacionais.

Event Loop

A chave que torna o Node.js tão eficiente é o conceito de Event Loop, com grande responsabilidade o Event Loop é basicamente um loop infinito, que a cada iteração verifica se temos eventos a serem executados na Task Queue, onde ele pega o evento e manda pra ser executado na Call Stack. Sua performance se dá pela forma que ele é executado, de forma não bloqueante, 

Powered by Rock Convert

Call Stack 

Em computação stack(pilha) é uma estrutura de dados que admite remoção de elementos e inserção de novos objetos, ela funciona usando a forma LIFO(Last in First Out), suas operações básicas são de push e pop (empilhar e desempilhar), uma pilha deve guardar em uma variável seu tamanho máximo, e quando esse tamanho é excedido temos um dos famosos erros dentro da programação(Stack Overflow), estouro da pilha.

Heap

Ela é a memória disponível para o processo do Node.js, toda vez que damos um new Object ou criamos uma variável para guardar um valor, é responsabilidade da Heap armazenar os valores.

Task Queue

Pode ser considerada como uma fila de mensagens, a serem processadas, quando temos chamadas como setTimeout, acesso a módulos de rede, I/O, entre outras, O Event loop analisa e verifica se é uma tarefa que vai exigir um processamento mais pesado, caso seja, ele envia estas execuções para a libuv, que as executa em uma pool de threads separada, permitindo que o V8 continue executando o código na thread principal, e caso seja um processo mais leve ele envia pra ser processado na call stack.

Um exemplo de função que tem um processamento mais pesado é o readFile do módulo fs do Node.js, a libuv administra essa função em outra thread, quando ela terminar de ser executada o callback será adicionado na fila Task Queue para ser executado na call stack assim que ela estiver disponível. 

Tá mas quem é o responsável por analisar se minha call stack está vazia, e se tem tarefas na Task Queue para serem processadas na call stack, o Event loop, é responsável por chamar as próximas tarefas enquanto o Node.js estiver rodando.

Macro e Micro Tasks

Até este ponto entendemos o funcionamento da call stack e como são organizadas nossas funções dentro da Task Queue. Mas dentro da Task Queue, temos dois tipos de tarefas, Uma é a micro tasks alguns exemplos(promises, process.nextTick) e outra é a macro tasks onde temos exemplos bem conhecidos no dia a dia do desenvolvimento, como setTimeout, setInterval.

Galera neste artigo tentei explicar de forma básica o funcionamento dos módulos que compõe a máquina virtual do Node.js, vou escrever mais conteúdo sobre o Node e seu funcionamento interno no futuro.

Espero que tenha ficado claro e qualquer dúvida comenta aqui, valeu!

Entre com seus dados para a ligação.