✨♻️ JavaScript em Imagens: Loop de Eventos
Tags: javascript
Published: 2022-11-04 20:52:26

Oh céus, o loop de eventos. 
É uma daquelas coisas que todo mundo que desenvolve em JavaScript tem que lidar de uma forma ou de outra, mas pode ser um pouco confuso de entender no início. Eu aprendo melhor de uma maneira mais visual, então pensei em tentar ajudar explicando de maneira visual através de gifs de baixa resolução.
Mas primeiro, o que é o loop de eventos e por que você deveria se importar?

JavaScript é **single-threaded**: apenas uma tarefa pode ser executada por vez. Normalmente isso não faz muita diferença, mas agora imagine que você está executando uma tarefa que leva 30 segundos. Toda a interface do usuário ficará travada por 30 segundos. 😬 É 2022, ninguém quer um site lento e sem resposta.

Felizmente, o navegador nos oferece alguns recursos que o próprio mecanismo JavaScript não fornece: uma API da Web. Isso inclui a DOM API, `setTimeout()`, requests HTTP e assim por diante. Isso pode nos ajudar a criar um comportamento assíncrono e sem bloqueio 🚀

Quando invocamos uma função, ela é adicionada a algo chamado pilha de chamadas - callstack. A pilha de chamadas faz parte do mecanismo JS, isso não é específico do navegador. É uma pilha, o que significa que o que está embaixo foi o primeiro a entrar e o último a sair (pense em uma pilha de panquecas). Quando uma função retorna um valor, ela é retirada da pilha 👋
![Funções são empurradas para a pilha de chamadas quando são invocadas e removidas quando retornam um valor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqk5abiptkr91gqy47j9.gif)
A função `respond()` retorna uma função `setTimeout()`. O `setTimeout()` é fornecido pela API da Web: ele permite atrasar tarefas sem bloquear o thread principal. A função de callback que passamos para a função `setTimeout()`, a arrow function `() => { return 'Hey' }` é adicionada à API da Web. Enquanto isso, a função `setTimeout()` e a função `respond()` são retiradas da pilha, e ambas retornam seus valores!
![setTimeout é fornecido pelo navegador, a Web API cuida do callback que passamos para ela](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c90e06c3mhlz8mshw0a9.gif)
Na Web API, um cronômetro é executado durante o tempo do segundo argumento que passamos para ele, 1000ms. O callback não é adicionado imediatamente à pilha de chamadas, em vez disso, é passado para algo chamado fila - queue.
![Quando o temporizador termina - 1000ms neste caso - o callback é passado para a fila de callbacks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lkneh7mdcxac4u99t15l.gif)
Esta parte pode ser um pouco confusa: isso não significa que a função de callback seja adicionada à pilha de chamadas (retornando um valor) após 1000ms! Ele simplesmente é adicionado à _fila_ após 1000ms. Mas é uma fila, a função tem que esperar a sua vez!
Agora esta é a parte que todos estávamos esperando... É hora do event loop fazer sua única tarefa: **conectar a fila (queue) com a pilha de chamadas (call stack)**! Se a pilha de chamadas estiver **vazia**, e se todas as funções invocadas anteriormente retornaram seus valores e foram retiradas da pilha, o _primeiro item_ da fila será adicionado à pilha de chamadas. Nesse caso, nenhuma outra função foi chamada, o que significa que a pilha de chamadas estava vazia quando a função de callback foi o primeiro item da fila.
![O loop de eventos examina a fila de callbacks e a pilha de chamadas. Se a pilha de chamadas estiver vazia, ela empurra o primeiro item da fila para a pilha](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0evzcozdfj690u56rck8.gif)
O callback é adicionado à pilha de chamadas, é invocado, retorna um valor e é retirado da pilha.
![O callback é adicionado à pilha de chamadas e executado. Depois de retornar um valor, ele é retirado da pilha de chamadas.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kbgd2oub6p7a1b5cfwu7.gif)
Ler um artigo é divertido, mas você só ficará totalmente confortável com isso trabalhando com ele repetidamente. Tente descobrir o que é registrado no console se executarmos o seguinte:
```javascript
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");

bar();
foo();
baz();
```
Entendeu? Vamos dar uma olhada rápida no que está acontecendo quando estamos executando este código em um navegador:
![Event loop schema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqxqqtz90vs5rmi4xdhf.gif)
1. Invocamos `bar()`. `bar()` retorna uma função `setTimeout()`.
2. O callback que passamos para `setTimeout()` é adicionado à Web API, a função `setTimeout()` e `bar()` são retiradas da pilha de chamadas.
3. O cronômetro é executado, enquanto isso `foo()` é invocado e registrado em primeiro lugar. `foo()` retorna (undefined), `baz()` é invocado e o callback é adicionado à fila.
4. `baz()` logga `Third`. O loop de eventos vê que a pilha de chamadas está vazia após o retorno de `baz()`, após o qual o callback é adicionado à pilha de chamadas.
5. O callback logga `Second`.

---

Espero que isso faça você se sentir um pouco mais confortável com o loop de eventos! Não se preocupe se ainda parecer confuso, o mais importante é **entender de onde certos erros/comportamentos podem vir** para pesquisar no **Google os termos certos com eficiência** e acabar na página correta do Stack Overflow 💪🏼 Sinta-se à vontade para entrar em contato comigo se você tiver alguma dúvida!

---

Essa é uma tradução da série de artigos [JavaScript Visualized](https://dev.to/lydiahallie/series/3341) criado com maestria por [Lydia Hallie](https://dev.to/lydiahallie).