Introdução ao Node.js (Single-Thread, Event-Loop e mercado)
Tags: javascript, programming, node, development
Published: 2023-11-28 02:19:54

Este capítulo não tem por finalidade contar a história do Node.js, afinal de contas o site oficial e o guia de inicio rápido fazem isso muito bem. Serei prático e objetivo ao abordar somente os conceitos essenciais, logo indispensáveis a qualquer “desenvolvedor aventureiro”.

---

## Livro

Este conteúdo representa um texto de amostra (primeira versão ainda em desenvolvimento) do Livro Node.js para iniciantes. Para acompanhar o desenvolvimento, acesse: https://github.com/fabiojaniolima/livros#livros

---

## O que é Node.js

No guia oficial de começo rápido (Quick Start), temos basicamente a seguinte introdução:

> O Node.js é um ambiente de tempo de execução JavaScript de código aberto e multiplataforma. É uma ferramenta popular para quase qualquer tipo de projeto!
>
> O Node.js executa o motor JavaScript V8, o núcleo do Google Chrome, fora do navegador. Isso permite que o Node.js seja muito eficiente.

_Para maiores detalhes a respeito, bem como para conhecer a história da plataforma, acesse: https://nodejs.dev/introduction-to-nodejs_

Em outras palavras, o Node.js é um runtime JavaScript server-side, ou seja, uma solução que possibilita ao desenvolvedor executar aplicações escritas em JavaScript do lado do servidor, de forma simples, rápida e performática. Isso é possível basicamente graças ao motor V8 e a biblioteca libuv — solução open-source para a qual dedicaremos mais algumas linhas logo adiante.

O JavaScript é considerado uma linguagem interpretado, porém, internamente o Node.js, mais precisamente o motor V8 realiza a compilação do código utilizando just-in-time (JIT) afim de acelerar o processo de execução do código.

## Uma sugestão de amigo

Antes de continuarmos, é muito importante que você tenha conhecimento dos links abaixo e gaste ao menos alguns minutos apreciando o que eles tem a oferecer:

  * A coleção de guias e artigos oficiais: https://nodejs.org/en/docs/guides

  * A documentação de referência das APIs nativas: https://nodejs.org/api

  * Stack Overflow, este é um espaço (fórum/comunidade) onde você poderá achar soluções para os problemas que irá encontrar durante a longa jornada: http://pt.stackoverflow.com

## Funcionamento básico

Muitos iniciantes enfrentam dificuldades ao tentar compreender o ciclo de vida dos eventos no Node.js. Pode parecer complexo à primeira vista, mas as aparências enganam. A compreensão deste processo se torna mais acessível ao focarmos em dois conceitos fundamentais: Single-Thread e Event-Loop.

### Single-Thread

Node.js é uma plataforma orientada a eventos que opera sob o princípio de uma única thread, gerenciando eficientemente a pilha de eventos ou Call Stack. Esta pilha adota a estratégia LIFO (Last In, First Out), onde a última entrada é a primeira a ser processada. As operações de fundo, ou background, são administradas por ‘workers’ que operam em segundo plano, e estes podem executar tarefas multi-thread.

Os "workers" são, essencialmente, processos de I/O assíncronos e não-bloqueantes, gerenciados pela libuv. Esta é uma biblioteca open-source, multiplataforma, escrita em C, que se vale de um pool de threads para gerir operações paralelas. A abordagem de thread única na gestão da Call Stack é vital para o alto desempenho do Node.js.

_🔗 Para uma exploração mais aprofundada deste conceito, sugiro consultar: The Node.js Event Loop, Timers, and process.nextTick()_

### Event-Loop

Ao tratar do Event-Loop, evitarei detalhar aspectos mais complexos e momentaneamente desnecessários, como Micro Task Queue, Next Tick Queue, Timers Queue, Immediates Queue, entre outros. Em vez disso, vamos nos concentrar no que de fato é relevante neste momento.

O Event-Loop é responsável por monitorar a Call Stack e processar eventos. Quando um evento é detectado e não representa uma operação extensa, ele é executado imediatamente. Operações mais longas, como leituras em disco ou comunicações de rede, são despachadas para um “worker” em um thread separado. Isso libera o Event-Loop para continuar processando outros eventos na pilha. Uma vez concluída a operação em segundo plano, sua função de callback é enfileirada e aguarda a liberação do Event-Loop para ser executada.

Este modelo permite que o Node.js lide eficientemente com I/O assíncrono, evitando bloqueios e mantendo a aplicação responsiva.

A seguir, apresento uma representação simplificada do Event-Loop e seu funcionamento, focando em transmitir a essência desse mecanismo de forma acessível:

![Representação simples e abstrata do Event-Loop.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/upc0la3hlm6ezj6aunho.png)

Talvez eu seja um pouco repetitivo agora, porém, vamos analisar a imagem acima aproveitando para revisar o que foi apresentado previamente:

No Node.js, os eventos são empilhados na Stack. O Event-Loop monitora essa Stack, identificando e processando eventos. Para eventos que não requerem operações extensas, a execução é imediata, permitindo que o Event-Loop passe rapidamente para o próximo evento.

Entretanto, eventos que envolvem “operações longas” — como leitura de arquivos ou comunicação de rede — são abordados de maneira diferente. Nesses casos, o Event-Loop delega a tarefa, junto com sua função de callback, ao Background Thread. Aqui, a libuv entra em cena, gerenciando a operação em um thread separado. Isso permite que o Event-Loop continue processando outros eventos na Stack sem interrupções.

Uma vez concluída a operação pelo Background Thread, a função de callback é colocada na Task Queue. O Event-Loop, que opera em uma única thread, só processará esta callback após finalizar as tarefas correntes na Stack. Esta abordagem assegura um gerenciamento eficiente de múltiplas tarefas pelo Event-Loop, alternando entre execuções rápidas de operações breves e o manejo de operações mais demoradas em segundo plano.

Esta estrutura é vital para a eficiência do Node.js, habilitando-o a lidar com um volume elevado de operações de I/O de forma não-bloqueante e assíncrona.

Veja um exemplo prático de funcionamento:

![Representação simples e abstrata do Event-Loop e seu funcionamento.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xxsj97pem1icjwuh9g48.png)

No exemplo ilustrado, temos dois eventos na Stack. O primeiro a ser processado é o `fs.readFile()`, seguindo o princípio LIFO (Last In, First Out) da Stack. Sendo `fs.readFile()` uma operação de I/O em disco — portanto, uma operação mais lenta e potencialmente bloqueante — ela é delegada para execução em background pela libuv.

Quando esta tarefa de leitura de arquivo é concluída, seu callback é colocado na Task Queue. Este callback aguardará sua vez para ser transferido para a Stack. E quando acontecerá essa transferência? Acontecerá quando a Stack estiver vazia. Nesse momento, o callback é movido da Task Queue para a Stack e, finalmente, processado pelo Event-Loop.

_Caso tenha interesse em aprofundar no assunto, acesse: https://dev.to/khaosdoctor/node-js-por-baixo-dos-panos-3-um-mergulho-no-event-loop-38l9 e https://imasters.com.br/front-end/node-js-o-que-e-esse-event-loop-afinal_

## Vantagens da plataforma

  * **Gerenciador de pacotes nativo (NPM)**: Instalando o Node.js, você obtém o NPM, um poderoso gerenciador de pacotes, facilitando o início do desenvolvimento.
  * **JavaScript em Todo Lugar**: Com o Node.js, o JavaScript, anteriormente limitado a funções de front-end, expande seu alcance para o back-end, mobile e desktop, dinamizando o desenvolvimento e a manutenção.
  * **Comunidade Ativa e Integrada**: A união das comunidades de Node.js e JavaScript promove uma sinergia poderosa, apoiando desde tarefas de desenvolvimento front-end até automações complexas.
  * **Eficiência e Leveza**: O modelo de Event-Loop do Node.js garante uma performance excepcional, otimizando o uso de RAM e CPU e evitando a sobrecarga por processos múltiplos.
I/O Não-Bloqueante: O Node.js lida com operações de I/O de forma assíncrona e não-bloqueante, mantendo a fluidez do fluxo de trabalho.
  * **Ecossistema Rico**: Com um vasto repositório de bibliotecas e módulos disponíveis no NPM, o Node.js atende a uma ampla gama de necessidades de desenvolvimento.
Multiplataforma: Funcionando em diversas plataformas como Windows, macOS e Linux, o Node.js oferece grande versatilidade.
  * **Ideal para Aplicações em Tempo Real**: Seu modelo assíncrono torna o Node.js perfeito para aplicações que exigem processamento em tempo real, como chats e jogos online.

## Quem está utilizando?

O Node.js é amplamente adotado por uma variedade de usuários, desde indivíduos até grandes corporações, incluindo empresas renomadas como:

  * Netflix
  * Trello
  * Paypal
  * LinkedIn
  * Walmart
  * Uber
  * Medium
  * Groupon
  * Ebay
  * NASA

E a lista vai longe…

## Vale a pena investir em JavaScript?

Dada a prevalência do JavaScript nas soluções baseadas no Node.js (incluindo TypeScript, que é transpilado para JavaScript), o investimento nesta linguagem é altamente vantajoso. Pesquisas anuais do Stack Overflow consistentemente classificam o JavaScript como uma das linguagens mais populares, reforçando sua relevância e demanda no mercado de desenvolvimento.

O Stack Overflow, reconhecida mundialmente como uma das comunidades mais influentes entre os desenvolvedores, realiza anualmente um levantamento detalhado sobre tecnologias, linguagens e tendências do setor de TI. Nas pesquisas realizadas de 2014 a 2021, a linguagem JavaScript destacou-se consistentemente, ocupando a posição de liderança no ranking das linguagens preferidas pelos desenvolvedores. Notavelmente, em 2013, o JavaScript ficou em segundo lugar, superado apenas pela linguagem SQL.

Em 2022:

![Relatório 2022. Fonte: https://survey.stackoverflow.co/2022#most-popular-technologies-language](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w0y2d0ipdnbfzi8vchcx.png)

_Acesse todos os relatórios em: https://insights.stackoverflow.com/survey_

Esses dados reforçam claramente a existência de uma demanda significativa no mercado para profissionais com conhecimento em JavaScript. O fato de a procura por essa habilidade permanecer elevada por um período extenso não apenas sugere uma necessidade constante desses profissionais, mas também sinaliza uma evolução contínua da tecnologia, atendendo e superando as expectativas do setor.

Vai JavaScript, ao infinito e além! 🚀🚀 🚀