Assincronismo e Event Loop em JavaScript

Por
Atualizado em
Publicado em
5 min. de leitura

Olá, querida(o) estudante! Neste artigo, vamos estudar um dos temas mais importantes — e mais cobrados — quando o assunto é JavaScript moderno e Node.js: o assincronismo e o funcionamento do event loop. Embora o JavaScript seja uma linguagem de execução em thread única, ele é amplamente utilizado para construir aplicações altamente concorrentes e escaláveis. Entender como isso é possível é fundamental tanto para o desenvolvimento profissional quanto para o desempenho em provas de concursos de TI.

Ao longo do texto, você verá como o JavaScript lida com operações assíncronas, qual é o papel do event loop, como funcionam async e await e por que o Node.js é considerado single-thread sem perder eficiência. Em seguida, analisaremos questões reais de concurso que exploram exatamente esses conceitos.

JavaScript e o modelo de execução single-thread

O JavaScript é uma linguagem que executa código em uma única thread, ou seja, apenas uma instrução é processada por vez no fluxo principal. Isso significa que, em teoria, operações demoradas poderiam travar a execução do programa. No entanto, a linguagem foi projetada para lidar com esse desafio por meio de um modelo assíncrono e orientado a eventos, permitindo que tarefas longas não bloqueiem a execução do restante do código.

Esse modelo é particularmente importante em ambientes como navegadores e servidores, onde o sistema precisa responder a múltiplas ações simultâneas, como cliques do usuário, requisições de rede ou leitura de arquivos.

O que é assincronismo em JavaScript

O assincronismo permite que determinadas operações sejam iniciadas e executadas em segundo plano, enquanto o fluxo principal do programa continua sendo executado. Em JavaScript, operações como requisições HTTP, timers, leitura de arquivos e acesso a banco de dados normalmente são assíncronas. Em vez de esperar o término dessas operações, o JavaScript delega sua execução a mecanismos internos e registra uma função de retorno para ser chamada quando a operação for concluída.

Esse comportamento é o que possibilita a criação de aplicações responsivas e escaláveis, mesmo com um único fluxo principal de execução.

Event Loop: o coração do JavaScript assíncrono

O event loop é o mecanismo responsável por coordenar a execução do código JavaScript. Ele monitora a call stack (pilha de execução) e as filas de tarefas assíncronas, verificando continuamente se há funções prontas para serem executadas. Quando a pilha está vazia, o event loop move tarefas pendentes da fila para a call stack, permitindo que sejam processadas.

Graças ao event loop, o JavaScript consegue gerenciar múltiplas operações assíncronas de forma organizada, mesmo sendo single-thread. Esse conceito é central em provas que abordam concorrência, execução de código e Node.js.

Callbacks, Promises e evolução do código assíncrono

Inicialmente, o JavaScript lidava com assincronismo por meio de callbacks, funções passadas como argumento para serem executadas após a conclusão de uma tarefa. Embora funcionais, callbacks frequentemente resultavam em códigos difíceis de ler e manter, conhecidos como callback hell. Para resolver esse problema, surgiram as Promises, que representam o resultado futuro de uma operação assíncrona e permitem encadeamentos mais claros.

Mais recentemente, o JavaScript introduziu async e await, que oferecem uma forma ainda mais legível de escrever código assíncrono, aproximando-o da escrita síncrona tradicional.

Async e await: simplificando o assincronismo

A palavra-chave async é usada para declarar funções que operam de forma assíncrona. Toda função marcada como async retorna, implicitamente, uma Promise. Já o await é utilizado dentro dessas funções para aguardar a resolução de uma Promise, suspendendo temporariamente a execução daquela função sem bloquear o fluxo principal do programa.

Esse modelo torna o código mais limpo, facilita o tratamento de erros com try/catch e elimina a necessidade de múltiplos callbacks aninhados.

Exemplo:

async function buscarDados() {

  const resposta = await fetch(“https://exemplo.com/api”);

  const dados = await resposta.json();

  console.log(dados);

}

Node.js, assincronismo e I/O (entrada/saída)

No ambiente Node.js, o assincronismo é ainda mais relevante. O Node foi projetado para lidar com operações de I/O (entrada/saída) não bloqueantes, como acesso a arquivos, rede e banco de dados. Embora o JavaScript execute em uma única thread, essas operações são delegadas a mecanismos internos, permitindo que o servidor continue respondendo a outras requisições enquanto aguarda os resultados.

Esse modelo explica por que o Node.js é amplamente utilizado em aplicações de rede e serviços de alta concorrência.

Vamos agora às questões de concurso!

1) Ano: 2025 Banca: IF Sul Rio-Grandense Órgão: IF Sul Rio-Grandense Prova: IF Sul Rio-Grandense – 2025 – IF Sul Rio-Grandense – Professor EBTT – Área 13, 17, 20, 25, 42: Informação e Comunicação I 

Observe o trecho de código a seguir, que faz uso dos comandos async/await na linguagem JavaScript. Esses comandos são utilizados para trabalhar com operações assíncronas de maneira mais simples e legível. 

async function getTodoData() {  try {  const response = await fetch(‘https://jsonplaceholder.typicode.com/todos/1’);  const data = await response.json();  console.log(data.title);  } catch (e) {  console.log(“Erro ao buscar dados”);  } } getTodoData(); console.log(“Depois de getTodoData”);

O código faz uma requisição à URL ‘https://jsonplaceholder.typicode.com/todos/1’ e, caso a resposta seja recebida com sucesso, o conteúdo será 

{“userId”:1,”id”:1,”title”:”delectus aut autem”,”completed”:false}

Quais serão as duas saídas apresentadas no console quando o código for executado?


a) undefined, “Depois de getTodoData”
b) “Depois de getTodoData”, “delectus aut autem”
c) “delectus aut autem”, “Depois de getTodoData”
d) “Erro ao buscar dados”, “Depois de getTodoData”

Gabarito: Letra B

Comentário

A função getTodoData é assíncrona. Ao ser chamada, a requisição fetch é iniciada, mas sua execução ocorre de forma assíncrona. Assim, o comando console.log(“Depois de getTodoData”) é executado antes da conclusão da requisição. Somente após a Promise ser resolvida é que o console.log(data.title) será executado. Portanto, a ordem correta das saídas é primeiro “Depois de getTodoData” e depois “delectus aut autem”.

Análise das alternativas:

  • A – Incorreta. O valor undefined não é impresso em nenhum ponto do código.
  • B – Correta. Reflete corretamente a ordem de execução assíncrona.
  • C – Incorreta. Inverte a ordem real de execução.
  • D – Incorreta. Não ocorre erro na requisição apresentada.

2) Ano: 2024 Banca: CESPE / CEBRASPE Órgão: MPO Prova: CESPE / CEBRASPE – 2024 – MPO – Analista de Planejamento e Orçamento – Especialidade: Desenvolvimento de Sistemas Orçamentários 

A respeito de linguagens de programação, julgue o item seguinte.

A execução do Node.js é single-thread, pois as requisições no ambiente são tratadas como eventos assíncronos e não bloqueáveis. 

Gabarito: Certo

Comentário

O Node.js executa o código JavaScript em uma única thread, mas utiliza um modelo assíncrono e orientado a eventos para tratar requisições de forma não bloqueante. Isso permite alta concorrência sem a criação de múltiplas threads de aplicação, característica central do Node.js.

3) Ano: 2025 Banca: IDCAP Órgão: IPJB Prova: IDCAP – 2025 – IPJB – Tecnologista – Tecnologia da Informação Aplicada a Conservação da Biodiversidade

Sobre o uso de async, await e event loop em JavaScript, analise as afirmações a seguir:

I.A palavra-chave async permite definir funções que operam de forma assíncrona, similar ao comportamento de Promises.

II.await pode ser utilizado em qualquer função JavaScript para aguardar a resolução de uma Promise, tornando o código mais legível e evitando callbacks aninhados.

III.O Event Loop é um mecanismo que permite a execução de código JavaScript em uma única thread, gerenciando eventos assíncronos como requisições de rede e timers.

É correto o que se afirma em:

  1. I, apenas.
  2. I e III, apenas.
  3. III, apenas.
  4. I, II e III.
  5. II, apenas.

Gabarito: Letra B 

Comentário

  • A afirmativa I está correta, pois funções async retornam Promises e operam de forma assíncrona.
  • A afirmativa II está incorreta, porque await só pode ser utilizado dentro de funções declaradas com async.
  • A afirmativa III está correta, pois o event loop permite que o JavaScript gerencie eventos assíncronos em um ambiente single-thread.

Conclusão

O assincronismo é um dos pilares do JavaScript moderno e do Node.js. Por meio do event loop, da execução single-thread e do uso de async/await, a linguagem consegue lidar com múltiplas operações simultâneas de forma eficiente e organizada. Esses conceitos são recorrentes em concursos de TI, especialmente quando as bancas exploram ordem de execução, concorrência e comportamento de código assíncrono. Dominar esses fundamentos é essencial tanto para a prática profissional quanto para um bom desempenho nas provas.

Referências

  • Flanagan, D. JavaScript: The Definitive Guide. O’Reilly, 2020.
  • Zakas, N. Understanding ECMAScript 6. No Starch Press, 2016.
  • Tilkov, S.; Vinoski, S. Node.js: Evented I/O for V8 JavaScript. IEEE, 2010.
  • Mozilla Developer Network (MDN).
  • Node.js Official Documentation – https://nodejs.org

Por
Atualizado em
Publicado em
5 min. de leitura