Image for post
Image for post

Event Loop JavaScript

Aprenda sobre o Loop de Eventos e como o JavaScript consegue fazer múltiplas tarefas ao mesmo tempo.

English version: https://www.javascripttutorial.net/javascript-event-loop/

O modelo "single-threaded" JavaScript

JavaScript é uma linguagem de programação de thread único (single-threaded). Ou seja, o motor JavaScript pode fazer apenas uma tarefa de cada vez.

O motor do JavaScript executa um script a partir do início e desce criando Contextos de Execuções, adicionando e retirando funções da Pilha de Chamadas.

Caso precisar, veja mais sobre a Pilha de Chamadas nesse tutorial:

Se você tem uma função que leva muito tempo para ser executada, não é possível fazer nada no navegador durante a sua execução. A página web simplesmente fica travada.

Uma função que leva muito tempo para ser executada é conhecida como Função de Bloqueio. Tecnicamente, as funções de bloqueio pausam todas as interações com a página web, até mesmo o clique do mouse.

Alguns exemplos de funções de bloqueio são funções que baixam arquivos de um servidor remoto ou funções que chamam uma API de um servidor externo.

Considere o seguinte script:

Image for post
Image for post

Neste exemplo temos um grande loop while dentro da função task() que emula uma tarefa demorada. A função task() é uma função de bloqueio.

O script apenas trava por alguns segundos (dependendo da velocidade do computador) e emite a seguinte saída:

Image for post
Image for post

Para executar o script, o motor JavaScript coloca a primeira chamada de console.log() no topo da pilha e a executa.

Em seguida o JavaScript coloca a função task() no topo da pilha de chamadas e executa essa função.

Porém vai demorar um pouco para concluir a função task(), então você verá a mensagem 'Download a file' alguns segundos de pois de 'Start script...'. Depois que a função task() é concluída, o motor JavaScript a tira da pilha de chamadas.

Por fim o JavaScript faz a última chamada, dessa vez chamando a função console.log('Done!') e a executa de forma bem rápida.

Image for post
Image for post

Chamadas de retorno para o resgate

Callbacks to the rescue

Para evitar que funções de bloqueio pausem outras atividades, normalmente você as envolve em funções de retorno de chamada (callbacks) que podem ser executadas posteriormente. Por exemplo:

Image for post
Image for post

Neste exemplo, você verá a mensagem 'Start script...' e 'Done' imediatamente. Somente depois de um tempo, você verá a mensagem 'Download a file.'.

Aqui está o resultado:

Image for post
Image for post

Como mencionado anteriormente, o JavaScript pode fazer apenas uma tarefa por vez. No entanto, é mais correto dizer que o tempo de execução (runtime) do JavaScript pode fazer uma coisa por vez.

O navegador de internet também possui outros componentes, não apenas o motor JavaScript. Quando você faz uma chamada da função setTimeout(), uma chamada AJAX ou clicar em um botão, o navegador é capaz de fazer essas atividades simultaneamente e de forma assíncrona.

O setTimeout(), chamadas AJAX e eventos DOM são partes de APIs do navegador de internet.

Em nosso exemplo, quando a função setTimeout() é chamada, ela é colocada na Pilha de Chamadas e a API Web cria um cronômetro que expirará em um segundo.

Image for post
Image for post

Em seguida, a função task() é colocada em uma fila chamada de Fila de Retorno de Chamada (callback queue) ou Fila de Tarefas (task queue):

Image for post
Image for post

O Loop de Eventos (Event Loop) é um processo em execução constante que monitora a fila de retorno de chamadas e a pilha de chamadas.

Se a Pilha de Chamadas não estiver vazia, o loop de eventos espera até que esteja vazia e coloca a próxima função da fila de retorno de chamada na pilha de chamadas. Se a fila de retorno de chamadas estiver vazia nada acontecerá:

Image for post
Image for post

Outro exemplo:

Image for post
Image for post

Neste exemplo, o tempo limite é 0 segundos, portanto a mensagem 'Execute immediately.' deveria aparecer antes da mensagem 'Bye!', mas não é isso que acontece.

A seguinte chamada:

Image for post
Image for post

É colocada na fila de retorno de chamada e executada apenas quando a pilha de chamadas está vazia. Em outras palavras, ela é executada somente após a chamada console.log('Bye!') ser concluída.

Aqui está o resultado:

Image for post
Image for post

A imagem a seguir ilustra o tempo de execução do JavaScript, API Web, Pilha de Chamadas e Loop de Eventos:

Image for post
Image for post

Neste tutorial você aprendeu sobre o Loop de Eventos do JavaScript, que é um processo em execução constante que coordena as tarefas entre a Pilha de Chamadas e a Fila de Retorno de Chamadas para obter a simultaneidade.

Veja o índice de todos os tutoriais JavaScript

Confira uma série de outros tutoriais JavaScript que eu escrevi, clicando no link abaixo:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store