aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/eventloop/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/pt-br/web/javascript/eventloop/index.html')
-rw-r--r--files/pt-br/web/javascript/eventloop/index.html161
1 files changed, 161 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/eventloop/index.html b/files/pt-br/web/javascript/eventloop/index.html
new file mode 100644
index 0000000000..f21206f175
--- /dev/null
+++ b/files/pt-br/web/javascript/eventloop/index.html
@@ -0,0 +1,161 @@
+---
+title: Modelo de Concorrência e Event Loop
+slug: Web/JavaScript/EventLoop
+tags:
+ - Avançado
+ - Event Loop
+ - Event Management
+ - Event Queue
+ - Handling Events
+ - JavaScript
+ - events
+translation_of: Web/JavaScript/EventLoop
+---
+<div>{{JsSidebar("Advanced")}}</div>
+
+<p><span class="seoSummary">O JavaScript possui um modelo de concorrência baseado em um <strong>event loop</strong> (<a href="https://pt.wikipedia.org/wiki/La%C3%A7o_de_eventos">laço de eventos</a>, em português), responsável pela execução do código, coleta e processamento de eventos e execução de subtarefas enfileiradas.</span> Este modelo é bem diferente de outras linguagens, como C ou Java, por exemplo.</p>
+
+<h2 id="Conceitos_de_runtime_tempo_de_execução">Conceitos de runtime (tempo de execução)</h2>
+
+<p>Os próximos tópicos irão explicar teoricamente o modelo. Interpretadores modernos de JavaScript implementam e otimizam fortemente as semânticas descritas.</p>
+
+<h3 id="Representação_visual">Representação visual</h3>
+
+<p style="text-align: center;"><img alt="Stack, heap, queue" src="/files/4617/default.svg" style="height: 270px; width: 294px;"></p>
+
+<h3 id="Pilha_Stack">Pilha (Stack)</h3>
+
+<p>As chamadas de funções criam uma pilha de <em>frames</em> (quadros).</p>
+
+<pre class="brush: js">function foo(b) {
+  var a = 10;
+  return a + b + 11;
+}
+
+function bar(x) {
+ var y = 3;
+ return foo(x * y);
+}
+
+console.log(bar(7)); //retorna 42
+</pre>
+
+<p>Quando chamamos a função <code>bar</code>, o primeiro <em>frame</em> é criado contendo argumentos e variáveis locais de <code>bar</code>. Quando a função <code>bar</code> chama <code>foo</code>, o segundo <em>frame</em> é criado e é colocado no topo da pilha contendo os argumentos e a variáveis locais de <code>foo</code>. Quando <code>foo</code> retorna, o <em>frame</em> do topo é removido da pilha (deixando apenas o <em>frame </em>da chamada de <code>bar</code>). Quando <code>bar</code> retorna, a pilha fica vazia.</p>
+
+<h3 id="Heap">Heap</h3>
+
+<p>Os objetos são alocados em um <em>heap </em>(acervo), que é apenas um nome para denotar uma grande região não estruturada da memória.</p>
+
+<h3 id="Fila_Queue">Fila (Queue)</h3>
+
+<p>O <em>runtime </em>do JavaScript contém uma fila de mensagens, que é uma lista de mensagens a serem processadas. Para cada mensagem, é associada uma função que é chamada para manipular a mensagem.</p>
+
+<p>Em algum ponto durante o {{anch("Event loop", "<em>event loop</em>")}}, o <em>runtime </em>começa a manipular as mensagens na fila, iniciando com a mais antiga. Para fazer isso, a mensagem é removida da fila e sua função correspondente é chamada junto com a mensagem. Como de costume, chamar uma função cria uma nova pilha de <em>frame</em> para o uso dessa função.</p>
+
+<p>O processamento de funções continua até que a pilha fique novamente vazia, então o <em>event loop</em> processará a próxima mensagem na fila (se houver uma).</p>
+
+<h2 id="Event_loop">Event loop</h2>
+
+<p><strong><em>Event loop</em></strong> tem esse nome por causa da forma que normalmente é implementado, geralmente é semelhante a:</p>
+
+<pre class="brush: js">while (queue.waitForMessage()) {
+ queue.processNextMessage();
+}</pre>
+
+<p><code>queue.waitForMessage</code> aguarda, de maneira síncrona, receber uma mensagem, se não houver nenhuma atualmente.</p>
+
+<h3 id="Run-to-completion">"Run-to-completion"</h3>
+
+<p>Cada mensagem é processada completamente antes de outra mensagem ser processada. Isso oferece um bom fundamento ao pensar sobre o seu software, incluindo o fato de que, independente de quando uma função é executada, ela não pode ser interrompida, ela será executada por completo, antes que outro código execute (e modifique dados que a função manipule). Isso é diferente do C, por exemplo, no qual uma função que está sendo executada em uma <em>thread</em>, pode ser interrompida a qualquer momento para executar um outro código em outra <em>thread</em>.</p>
+
+<p>O lado negativo deste modelo é que se uma mensagem levar muito tempo para ser finalizada, a aplicação web fica indisponível para processar as interações do usuário, como cliques ou rolagens. O navegador mitiga este problema através do aviso: "<em>Um script desta página pode estar ocupado</em>". Uma boa prática a seguir é fazer o processamento de mensagens curtas, e se possível, dividir uma mensagem em múltiplas mensagens.</p>
+
+<h3 id="Adicionando_mensagens">Adicionando mensagens</h3>
+
+<p>Nos navegadores, as mensagens são adicionadas a qualquer momento que um evento é acionado, se este possuir um "<em>listener</em>". Caso não possua, o evento será ignorado. Assim, um clique em um elemento com um manipulador de eventos de clique adicionará uma mensagem, igualmente como qualquer outro evento.</p>
+
+<p>A função <code><a href="/en-US/docs/Web/API/WindowTimers.setTimeout">setTimeout</a></code><a href="/en-US/docs/Web/API/WindowTimers.setTimeout"> </a>é chamada com 2 argumentos: uma mensagem para adicionar à fila (queue) e um valor em tempo (opcional, padrão é 0). O valor em tempo representa o intervalo (mínimo) com que a mensagem será realmente enviada a fila. Se não houver outra mensagem na fila, a mensagem será processada logo após o intervalo, no entanto, se houver mensagens, a mensagem <code>setTimeout</code> terá que esperar até que outras mensagens sejam finalizadas. Por esse motivo, o segundo argumento indica um tempo mínimo e não um tempo garantido.</p>
+
+<p>Aqui está um exemplo que demonstra esse conceito (<code>setTimeout</code> não é executado imediatamente após o temporizador expirar):</p>
+
+<pre class="brush: js">const s = new Date().getSeconds();
+
+setTimeout(function() {
+ // imprime "2", o que significa que o callback não é chamado imediatamente após 500 milissegundos.
+ console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
+}, 500);
+
+while(true) {
+ if(new Date().getSeconds() - s &gt;= 2) {
+ console.log("Good, looped for 2 seconds");
+ break;
+ }
+}
+</pre>
+
+<h3 id="Intervalos_de_zero_segundos">Intervalos de zero segundos</h3>
+
+<p>O intervalo zero não significa, necessariamente, que o <em>callback</em> será disparado após zero milissegundos. Chamar {{domxref("WindowTimers.setTimeout", "setTimeout")}} com um intervalo de 0 (zero) milissegundos não executa a função do <em>callback </em>após dado intervalo.</p>
+
+<p>A execução depende do número de mensagens em espera na fila. No exemplo abaixo, a mensagem ''<em>this is just a message</em>'' será escrita no console antes que a mensagem do <em>callback</em> seja processada, isso acontece porque o intervalo definido na função indica o tempo mínimo necessário para que a aplicação processe a requisição, mas não é um tempo garantido.</p>
+
+<p>Basicamente, <code>setTimeout</code> precisa esperar que todo o código das mensagens enfileiradas seja concluído, mesmo que você tenha especificado um tempo limite específico para o seu <code>setTimeout</code>.</p>
+
+<pre class="brush: js">(function() {
+
+ console.log('this is the start');
+
+ setTimeout(function cb() {
+ console.log('Callback 1: this is a msg from call back');
+ }); // tem um valor de tempo padrão de 0
+
+ console.log('this is just a message');
+
+ setTimeout(function cb1() {
+ console.log('Callback 2: this is a msg from call back');
+ }, 0);
+
+ console.log('this is the end');
+
+})();
+
+// "this is the start"
+// "this is just a message"
+// "this is the end"
+// "Callback 1: this is a msg from call back"
+// "Callback 2: this is a msg from call back"
+</pre>
+
+<h3 id="Múltiplos_runtimes_comunicando-se_em_conjunto">Múltiplos runtimes comunicando-se em conjunto</h3>
+
+<p>Um web worker ou um <code>iframe</code> com uma diferente origem (<a href="/pt-BR/docs/Web/HTTP/Controle_Acesso_CORS">cross-origin</a>) tem as suas próprias pilhas, heaps e filas de messagens. Dois runtimes distintos só podem se comunicar por meio do envio de mensagens, via método <a href="/en-US/docs/DOM/window.postMessage" title="/en-US/docs/DOM/window.postMessage"><code>postMessage</code></a>. Este método adiciona uma mensagem ao outro runtime, se este escutar os eventos de <code>message</code>.</p>
+
+<h2 id="Sem_bloqueio">Sem bloqueio</h2>
+
+<p>Uma propriedade muito interessante do modelo "<em>event loop</em>", é que o JavaScript, ao contrário de muitas outras linguagens, nunca bloqueia. A manipulação de E/S<em> </em>é tipicamente realizada através de eventos e <em>callbacks</em>, portanto, quando uma aplicação está esperando por um retorno de uma consulta do <a href="/pt-BR/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a> ou o retorno de uma requisição <a href="/pt-BR/docs/Web/API/XMLHttpRequest" title="/en-US/docs/DOM/XMLHttpRequest">XHR</a>, este ainda pode processar outras coisas, como as ações do usuário.</p>
+
+<p>Exceções de legado existem, como por exemplo, <code>alert</code> ou XHR síncrono, mas é considerado uma boa prática evitá-los. Tome cuidado, <a href="http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded/2734311#2734311" title="http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded/2734311#2734311">exceções a exceção existem</a> (mas geralmente são, mais do que qualquer coisa, bugs de implementação).</p>
+
+<h2 id="Especificações">Especificações</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Especificação</th>
+ <th scope="col">Status</th>
+ <th scope="col">Comentário</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{SpecName('HTML WHATWG', 'webappapis.html#event-loops', 'Event loops')}}</td>
+ <td>{{Spec2('HTML WHATWG')}}</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#what-is-the-event-loop">Node.js Event Loop</a></td>
+ <td>Living Standard</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>