aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/learn/javascript/asynchronous
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/pt-br/learn/javascript/asynchronous
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/pt-br/learn/javascript/asynchronous')
-rw-r--r--files/pt-br/learn/javascript/asynchronous/conceitos/index.html155
-rw-r--r--files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html523
-rw-r--r--files/pt-br/learn/javascript/asynchronous/index.html67
-rw-r--r--files/pt-br/learn/javascript/asynchronous/introdução/index.html283
-rw-r--r--files/pt-br/learn/javascript/asynchronous/promises/index.html586
-rw-r--r--files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html624
6 files changed, 2238 insertions, 0 deletions
diff --git a/files/pt-br/learn/javascript/asynchronous/conceitos/index.html b/files/pt-br/learn/javascript/asynchronous/conceitos/index.html
new file mode 100644
index 0000000000..f2e6759f41
--- /dev/null
+++ b/files/pt-br/learn/javascript/asynchronous/conceitos/index.html
@@ -0,0 +1,155 @@
+---
+title: Conceitos gerais da programação assíncrona
+slug: Learn/JavaScript/Asynchronous/Conceitos
+translation_of: Learn/JavaScript/Asynchronous/Concepts
+---
+<div>{{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p>Neste artigo, nós vamos ver um número de conceitos importantes relativos à programação assíncrona e como ela se parece em navegadores modernos e em JavaScript. Você deve entender estes conceitos antes de trabalhar com outros artigos neste módulo.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Conhecimentos básicos de informática e compreensão dos fundamentos de JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Entender os conceitos básicos da programação assíncrona e como ela se manifesta em navegadores e JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Assíncrono">Assíncrono?</h2>
+
+<p>Normalmente, o código de um programa é executado de forma direta, com uma coisa acontecendo por vez. Se uma função depende do resultado de outra função, ela tem que esperar o retorno do resultado, e até que isso aconteça, o programa inteiro praticamente para de funcionar da perspectiva do usuário.</p>
+
+<p>Usuários do Mac, por exemplo, conseguem ver isso como o cursor giratório em arco-íris (ou "beachball", como normalmente é chamado). Este cursor é o jeito do sistema operacional dizer: "o programa atual que você está usando teve que parar e esperar algo terminar de ser executado, e estava demorando tanto que fiquei preocupado se você estava pensando no que aconteceu."</p>
+
+<p><img alt="Multi-colored macOS beachball busy spinner" src="https://mdn.mozillademos.org/files/16577/beachball.jpg" style="display: block; float: left; height: 256px; margin: 0px 30px 0px 0px; width: 250px;"></p>
+
+<p>Essa é uma situação frustrante, e não faz bom uso do poder de processamento do computador — especialmente em uma era em que computadores tem múltiplos núcleos de processamento disponíveis. Não há sentido em ficar esperando por algo quando você pode deixar outra tarefa ser executada em um núcleo de processador diferente e deixar que ele te avise quando terminar. Isso te permite fazer mais coisas por enquanto, o que é a base da <strong>programação assincrona</strong>. Depende do ambiente de programação que você está usando (navegadores da Web, no caso de desenvolvimento da Web) para fornecer APIs que permitem executar essas tarefas de forma assíncrona.</p>
+
+<h2 id="Bloqueio_de_código">Bloqueio de código</h2>
+
+<p>Técnicas <strong>async</strong> (assíncronas) são muito úteis, principalmente na programação web. Quando um aplicativo web é executado em um navegador e executa um pedaço de código rigoroso sem retornar o controle para o navegador, ele pode parecer que travou. Isso é chamado de <strong>blocking</strong>; o navegador está bloqueado de continuar a manusear a entrada do usuário e de realizar outras tarefas até que o aplicativo web retorne o controle do processador.</p>
+
+<p>Vamos dar uma olhadinha em alguns exemplos para que você entenda o blocking.</p>
+
+<p>No nosso exemplo <a href="https://github.com/mdn/learning-area/tree/master/javascript/asynchronous/introducing/simple-sync.html">simple-sync.html</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync.html">veja aqui</a>), nós adicionamos um evento de click em um botão para que, quando clicado, ele executa uma tarefa pesada (calcula 10 milhões de datas e depois imprime a última delas no console) e depois adiciona um parágrafo no DOM:</p>
+
+<pre class="brush: js notranslate">const btn = document.querySelector('button');
+btn.addEventListener('click', () =&gt; {
+ let myDate;
+ for(let i = 0; i &lt; 10000000; i++) {
+ let date = new Date();
+ myDate = date
+ }
+
+ console.log(myDate);
+
+ let pElem = document.createElement('p');
+ pElem.textContent = 'This is a newly-added paragraph.';
+ document.body.appendChild(pElem);
+});</pre>
+
+<p>Quando o exemplo for executado, abra seu console JavaScript e depois clique no botão  — você verá qua o parágrafo não aparece até que o programa termine de calcular as datas e imprimir a última no console. O código é executado na ordem em que ele aparece na fonte, e a operação seguinte só é executada depois que a primeira for terminada.</p>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: O exemplo anterior não é muito realistico. Você nunca calcularia 10 milhões de datas em um aplicativo real! Mas isso serve par te dar um apoio sobre o assunto.</p>
+</div>
+
+<p>No nosso segundo exemplo <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/simple-sync-ui-blocking.html">simple-sync-ui-blocking.html</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync-ui-blocking.html">veja aqui</a>), nós simulamos algo mais realistico que você pode encontrar em uma página real. Nós bloqueamos a interatividade do usuário na renderização da UI. Neste exemplo, nós temos dois botões:</p>
+
+<ul>
+ <li>Um botão "Fill canvas" que quando for clicado renderiza 1 milhão de círculos azuis no elemento {{htmlelement("canvas")}} .</li>
+ <li>Um botão "Clique-me" que mostra um alerta quando clicado.</li>
+</ul>
+
+<pre class="brush: js notranslate">function expensiveOperation() {
+ for(let i = 0; i &lt; 1000000; i++) {
+ ctx.fillStyle = 'rgba(0,0,255, 0.2)';
+ ctx.beginPath();
+ ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false);
+ ctx.fill()
+ }
+}
+
+fillBtn.addEventListener('click', expensiveOperation);
+
+alertBtn.addEventListener('click', () =&gt;
+ alert('You clicked me!')
+);</pre>
+
+<p>Se você clicar no primeiro botão e imediatamente no segundo, você verá que a mensagem de alerta não aparece até que os círculos sejam totalmente renderizados. A primeira operação bloqueia a segunda até a sua finalização.</p>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: OK, no nosso caso, isso é ruim e estamos bloqueando o código de propósito, mas isso é um problema comum que desenvolvedores de aplicativos reais sempre tentam resolver.</p>
+</div>
+
+<p>E por quê isso acontece? A resposta é que o JavaScript é <strong>single threaded</strong>. E é neste ponto que precisamos introduzir a você o conceito de <strong>threads</strong>.</p>
+
+<h2 id="Threads">Threads</h2>
+
+<p>Uma <strong>thread</strong> é basicamente um único processo que um programa pode usar para concluir tarefas. Cada thread só pode fazer uma tarefa de cada vez:</p>
+
+<pre class="notranslate">Tarefa A --&gt; Tarefa B --&gt; Tarefa C</pre>
+
+<p>Cada tarefa será executada sequencialmente; uma tarefa tem que ser concluída antes que a próxima possa ser iniciada.</p>
+
+<p>Como foi dito anteriormente, muitos computadores possuem múltiplos núcleos, para que possam fazer múltiplas coisas de uma vez só. Linguagens de programação que podem suportar múltiplas threads podem usar múltiplos processadores para concluir múltiplas tarefas simultâneamente:</p>
+
+<pre class="notranslate">Thread 1: Tarefa A --&gt; Tarefa B
+Thread 2: Tarefa C --&gt; Tarefa D</pre>
+
+<h3 id="JavaScript_é_single_threaded">JavaScript é single threaded</h3>
+
+<p>JavaScript é tradicionalmente single-threaded. Mesmo com múltiplos núcleos de processamento, você só pode fazê-lo executar tarefas em uma única thread, chamada de <strong>main thread</strong> (thread principal). Nosso exemplo de cima é executado assim:</p>
+
+<pre class="notranslate">Main thread: Renderizar circulos no canvas --&gt; Mostrar alert()</pre>
+
+<p>Depois de um tempo, o JavaScript ganhou algumas ferramentas para ajudar em tais problemas. As <a href="/en-US/docs/Web/API/Web_Workers_API">Web workers</a> te permitem mandar parte do processamento do JavaScript para uma thread separada. Você geralmente usaria uma worker para executar um processo pesado para que a UI não seja bloqueada.</p>
+
+<pre class="notranslate"> Main thread: Tarefa A --&gt; Tarefa C
+Worker thread: Tarefa pesada B</pre>
+
+<p>Com isso em mente, dê uma olhada em <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/simple-sync-worker.html">simple-sync-worker.html</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync-worker.html">veja aqui</a>), com o seu console JavaScript aberto. Isso é uma nova versão do nosso exemplo que calcula 10 milhões de datas em uma tread worker separada. Agora, quando você clica no botão, o navegador é capaz de mostrar o parágrafo antes que as datas sejam terminadas. A primeira opreção não bloqueia a segunda.</p>
+
+<h2 id="Código_assíncrono">Código assíncrono</h2>
+
+<p>Web workers podem ser bem úteis, mas elas tem as suas limitações. Uma delas é que elas não são capazes de acessar a {{Glossary("DOM")}} — você não pode fazer com que uma worker faça algo diretamente para atualizar a UI. Nós não poderíamos renderizar nossos 1 milhão de círculos azuis na nossa worker; basicamente ela pode apenas fazer cálculos de números.</p>
+
+<p>O segundo problema é que, mesmo que o código executado em uma worker não cause um bloqueio, ele ainda é um código síncrono. Isso se torna um problema quando uma função depende dos resultados de processos anteriores para funcionar. Considere os diagramas a seguir:</p>
+
+<pre class="notranslate">Main thread: Tarefa A --&gt; Tarefa B</pre>
+
+<p>Nesse caso, digamos que a tarefa A está fazendo algo como pegar uma imagem do servidor e que a tarefa B faz algo com essa imagem, como colocar um filtro nela. Se você iniciar a tarefa A e depois tentar executar a tarefa B imediatamente, você obterá um erro, porque a imagem não estará disponível ainda.</p>
+
+<pre class="notranslate"> Main thread: Tarefa A --&gt; Tarefa B --&gt; |Tarefa D|
+Worker thread: Tarefa C ---------------&gt; | |</pre>
+
+<p>Neste caso, digamos que a tarefa D faz uso dos resultados das tarefas B e C. Se nós pudermos garantir que esses resultados estejam disponíveis ao mesmo tempo, então tudo talvez esteja bem, mas isso não é garantido. Se a tarefa D tentar ser executada quando um dos resultados não estiver disponível, ela retornará um erro.</p>
+
+<p>Para consertarmos tais problemas, os browsers nos permitem executar certas operações de modo assíncrono. Recursos como <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> te permitem executar uma operação e depois esperar pelo resultado antes de executar outra operação: </p>
+
+<pre class="notranslate">Main thread: Tarefa A Tarefa B
+ Promise: |___operação async___|</pre>
+
+<p>Já que a operação está acontecendo em outro lugar, a main thread não está bloqueada enquanto a operação assíncrona está sendo processada.</p>
+
+<p>Nós vamos começar a olhar em como podemos escrever código assíncrono no próximo artigo.</p>
+
+<h2 id="Conclusão">Conclusão</h2>
+
+<p>O design moderno de software gira em torno do uso de programação assíncrona, para permitir que os programas façam mais de uma coisa por vez. Ao usar APIs mais novas e mais poderosas, você encontrará mais casos em que a única maneira de fazer as coisas é assincronamente. Costumava ser difícil escrever código assíncrono. Ainda é preciso se acostumar, mas ficou muito mais fácil. No restante deste módulo, exploraremos ainda mais por que o código assíncrono é importante e como projetar o código que evita alguns dos problemas descritos acima.</p>
+
+<h2 id="Nesse_módulo">Nesse módulo</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">Conceitos gerais da programação assíncrona</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introduzindo o JavaScript assíncrono</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Timeouts e intervalos</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Código elegante usando as Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Facilitando a programação async com async e await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Escolhendo a abordagem certa</a></li>
+</ul>
diff --git a/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html b/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html
new file mode 100644
index 0000000000..254bc41a99
--- /dev/null
+++ b/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html
@@ -0,0 +1,523 @@
+---
+title: Escolhendo a abordagem correta
+slug: Learn/JavaScript/Asynchronous/Escolhendo_abordagem_correta
+translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p>To finish this module off, we'll provide a brief discussion of the different coding techniques and features we've discussed throughout, looking at which one you should use when, with recommendations and reminders of common pitfalls where appropriate. We'll probably add to this resource as time goes on.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>Basic computer literacy, a reasonable understanding of JavaScript fundamentals.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To be able to make a sound choice of when to use different asynchronous programming techniques.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Asynchronous_callbacks">Asynchronous callbacks</h2>
+
+<p>Generally found in old-style APIs, involves a function being passed into another function as a parameter, which is then invoked when an asynchronous operation has been completed, so that the callback can in turn do something with the result. This is the precursor to promises; it's not as efficient or flexible. Use only when necessary.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>No</td>
+ <td>Yes (recursive callbacks)</td>
+ <td>Yes (nested callbacks)</td>
+ <td>No</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Code_example">Code example</h3>
+
+<p>An example that loads a resource via the <a href="/en-US/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code> API</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/xhr-async-callback.html">run it live</a>, and <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/xhr-async-callback.html">see the source</a>):</p>
+
+<pre class="brush: js notranslate">function loadAsset(url, type, callback) {
+ let xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = type;
+
+ xhr.onload = function() {
+ callback(xhr.response);
+ };
+
+ xhr.send();
+}
+
+function displayImage(blob) {
+ let objectURL = URL.createObjectURL(blob);
+
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);</pre>
+
+<h3 id="Pitfalls">Pitfalls</h3>
+
+<ul>
+ <li>Nested callbacks can be cumbersome and hard to read (i.e. "callback hell").</li>
+ <li>Failure callbacks need to be called once for each level of nesting, whereas with promises you can just use a single <code>.catch()</code> block to handle the errors for the entire chain.</li>
+ <li>Async callbacks just aren't very graceful.</li>
+ <li>Promise callbacks are always called in the strict order they are placed in the event queue; async callbacks aren't.</li>
+ <li>Async callbacks lose full control of how the function will be executed when passed to a third-party library.</li>
+</ul>
+
+<h3 id="Browser_compatibility">Browser compatibility</h3>
+
+<p>Really good general support, although the exact support for callbacks in APIs depends on the particular API. Refer to the reference documentation for the API you're using for more specific support info.</p>
+
+<h3 id="Further_information">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a>, in particular <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing#Async_callbacks">Async callbacks</a></li>
+</ul>
+
+<h2 id="setTimeout">setTimeout()</h2>
+
+<p><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code> is a method that allows you to run a function after an arbitrary amount of time has passed.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ <tr>
+ <td>Yes</td>
+ <td>Yes (recursive timeouts)</td>
+ <td>Yes (nested timeouts)</td>
+ <td>No</td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Code_example_2">Code example</h3>
+
+<p>Here the browser will wait two seconds before executing the anonymous function, then will display the alert message (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">see it running live</a>, and <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">see the source code</a>):</p>
+
+<pre class="brush: js notranslate">let myGreeting = setTimeout(function() {
+ alert('Hello, Mr. Universe!');
+}, 2000)</pre>
+
+<h3 id="Pitfalls_2">Pitfalls</h3>
+
+<p>You can use recursive <code>setTimeout()</code> calls to run a function repeatedly in a similar fashion to <code>setInterval()</code>, using code like this:</p>
+
+<pre class="brush: js notranslate">let i = 1;
+setTimeout(function run() {
+ console.log(i);
+ i++;
+
+ setTimeout(run, 100);
+}, 100);</pre>
+
+<p>There is a difference between recursive <code>setTimeout()</code> and <code>setInterval()</code>:</p>
+
+<ul>
+ <li>Recursive <code>setTimeout()</code> guarantees at least the specified amount of time (100ms in this example) will elapse between the executions; the code will run and then wait 100 milliseconds before it runs again. The interval will be the same regardless of how long the code takes to run.</li>
+ <li>With <code>setInterval()</code>, the interval we choose <em>includes</em> the time taken to execute the code we want to run in. Let's say that the code takes 40 milliseconds to run — the interval then ends up being only 60 milliseconds.</li>
+</ul>
+
+<p>When your code has the potential to take longer to run than the time interval you’ve assigned, it’s better to use recursive <code>setTimeout()</code> — this will keep the time interval constant between executions regardless of how long the code takes to execute, and you won't get errors.</p>
+
+<h3 id="Browser_compatibility_2">Browser compatibility</h3>
+
+<p>{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}</p>
+
+<h3 id="Further_information_2">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a>, in particular <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals#setTimeout()">setTimeout()</a></li>
+ <li><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout() reference</a></li>
+</ul>
+
+<h2 id="setInterval">setInterval()</h2>
+
+<p><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code> is a method that allows you to run a function repeatedly with a set interval of time between each execution. Not as efficient as <code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code>, but allows you to choose a running rate/frame rate.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ <tr>
+ <td>No</td>
+ <td>Yes</td>
+ <td>No (unless it is the same one)</td>
+ <td>No</td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Code_example_3">Code example</h3>
+
+<p>The following function creates a new <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date()</a></code> object, extracts a time string out of it using <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString">toLocaleTimeString()</a></code>, and then displays it in the UI. We then run it once per second using <code>setInterval()</code>, creating the effect of a digital clock that updates once per second (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">see this live</a>, and also <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">see the source</a>):</p>
+
+<pre class="brush: js notranslate">function displayTime() {
+ let date = new Date();
+ let time = date.toLocaleTimeString();
+ document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);</pre>
+
+<h3 id="Pitfalls_3">Pitfalls</h3>
+
+<ul>
+ <li>The frame rate isn't optimized for the system the animation is running on, and can be somewhat inefficient. Unless you need to choose a specific (slower) framerate, it is generally better to use <code>requestAnimationFrame()</code>.</li>
+</ul>
+
+<h3 id="Browser_compatibility_3">Browser compatibility</h3>
+
+<p>{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}</p>
+
+<h3 id="Further_information_3">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a>, in particular <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></li>
+ <li><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval() reference</a></li>
+</ul>
+
+<h2 id="requestAnimationFrame">requestAnimationFrame()</h2>
+
+<p><code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code> is a method that allows you to run a function repeatedly, and efficiently, at the best framerate available given the current browser/system. You should, if at all possible, use this instead of <code>setInterval()</code>/recursive <code>setTimeout()</code>, unless you need a specific framerate.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ <tr>
+ <td>No</td>
+ <td>Yes</td>
+ <td>No (unless it is the same one)</td>
+ <td>No</td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Code_example_4">Code example</h3>
+
+<p>A simple animated spinner; you can find this <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">example live on GitHub</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">source code</a> also):</p>
+
+<pre class="brush: js notranslate">const spinner = document.querySelector('div');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+
+function draw(timestamp) {
+ if(!startTime) {
+ startTime = timestamp;
+ }
+
+ rotateCount = (timestamp - startTime) / 3;
+
+ if(rotateCount &gt; 359) {
+ rotateCount %= 360;
+ }
+
+ spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
+
+ rAF = requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<h3 id="Pitfalls_4">Pitfalls</h3>
+
+<ul>
+ <li>You can't choose a specific framerate with <code>requestAnimationFrame()</code>. If you need to run your animation at a slower framerate, you'll need to use <code>setInterval()</code> or recursive <code>setTimeout()</code>.</li>
+</ul>
+
+<h3 id="Browser_compatibility_4">Browser compatibility</h3>
+
+<p>{{Compat("api.Window.requestAnimationFrame")}}</p>
+
+<h3 id="Further_information_4">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a>, in particular <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals#requestAnimationFrame()">requestAnimationFrame()</a></li>
+ <li><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame() reference</a></li>
+</ul>
+
+<h2 id="Promises">Promises</h2>
+
+<p><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> are a JavaScript feature that allows you to run asynchronous operations and wait until it is definitely complete before running another operation based on its result. Promises are the backbone of modern asynchronous JavaScript.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ <tr>
+ <td>No</td>
+ <td>No</td>
+ <td>Yes</td>
+ <td>See <code>Promise.all()</code>, below</td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Code_example_5">Code example</h3>
+
+<p>The following code fetches an image from the server and displays it inside an {{htmlelement("img")}} element; <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/simple-fetch-chained.html">see it live also</a>, and see also <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/simple-fetch-chained.html">the source code</a>:</p>
+
+<pre class="brush: js notranslate">fetch('coffee.jpg')
+.then(response =&gt; response.blob())
+.then(myBlob =&gt; {
+ let objectURL = URL.createObjectURL(myBlob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+})
+.catch(e =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + e.message);
+});</pre>
+
+<h3 id="Pitfalls_5">Pitfalls</h3>
+
+<p>Promise chains can be complex and hard to parse. If you nest a number of promises, you can end up with similar troubles to callback hell. For example:</p>
+
+<pre class="brush: js notranslate">remotedb.allDocs({
+ include_docs: true,
+ attachments: true
+}).then(function (result) {
+ let docs = result.rows;
+ docs.forEach(function(element) {
+ localdb.put(element.doc).then(function(response) {
+ alert("Pulled doc with id " + element.doc._id + " and added to local db.");
+ }).catch(function (err) {
+ if (err.name == 'conflict') {
+ localdb.get(element.doc._id).then(function (resp) {
+ localdb.remove(resp._id, resp._rev).then(function (resp) {
+// et cetera...</pre>
+
+<p>It is better to use the chaining power of promises to go with a flatter, easier to parse structure:</p>
+
+<pre class="brush: js notranslate">remotedb.allDocs(...).then(function (resultOfAllDocs) {
+ return localdb.put(...);
+}).then(function (resultOfPut) {
+ return localdb.get(...);
+}).then(function (resultOfGet) {
+ return localdb.put(...);
+}).catch(function (err) {
+ console.log(err);
+});</pre>
+
+<p>or even:</p>
+
+<pre class="brush: js notranslate">remotedb.allDocs(...)
+.then(resultOfAllDocs =&gt; {
+ return localdb.put(...);
+})
+.then(resultOfPut =&gt; {
+ return localdb.get(...);
+})
+.then(resultOfGet =&gt; {
+ return localdb.put(...);
+})
+.catch(err =&gt; console.log(err));</pre>
+
+<p>That covers a lot of the basics. For a much more complete treatment, see the excellent <a href="https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">We have a problem with promises</a>, by Nolan Lawson.</p>
+
+<h3 id="Browser_compatibility_5">Browser compatibility</h3>
+
+<p>{{Compat("javascript.builtins.Promise")}}</p>
+
+<h3 id="Further_information_5">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">Using promises</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise reference</a></li>
+</ul>
+
+<h2 id="Promise.all">Promise.all()</h2>
+
+<p>A JavaScript feature that allows you to wait for multiple promises to complete before then running a further operation based on the results of all the other promises.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ <tr>
+ <td>No</td>
+ <td>No</td>
+ <td>No</td>
+ <td>Yes</td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Code_example_6">Code example</h3>
+
+<p>The following example fetches several resources from the server, and uses <code>Promise.all()</code> to wait for all of them to be available before then displaying all of them — <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/promise-all.html">see it live</a>, and see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-all.html">source code</a>:</p>
+
+<pre class="brush: js notranslate">function fetchAndDecode(url, type) {
+ // Returning the top level promise, so the result of the entire chain is returned out of the function
+ return fetch(url).then(response =&gt; {
+ // Depending on what type of file is being fetched, use the relevant function to decode its contents
+ if(type === 'blob') {
+ return response.blob();
+ } else if(type === 'text') {
+ return response.text();
+ }
+ })
+ .catch(e =&gt; {
+ console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
+ });
+}
+
+// Call the fetchAndDecode() method to fetch the images and the text, and store their promises in variables
+let coffee = fetchAndDecode('coffee.jpg', 'blob');
+let tea = fetchAndDecode('tea.jpg', 'blob');
+let description = fetchAndDecode('description.txt', 'text');
+
+// Use Promise.all() to run code only when all three function calls have resolved
+Promise.all([coffee, tea, description]).then(values =&gt; {
+ console.log(values);
+ // Store each value returned from the promises in separate variables; create object URLs from the blobs
+ let objectURL1 = URL.createObjectURL(values[0]);
+ let objectURL2 = URL.createObjectURL(values[1]);
+ let descText = values[2];
+
+ // Display the images in &lt;img&gt; elements
+ let image1 = document.createElement('img');
+ let image2 = document.createElement('img');
+ image1.src = objectURL1;
+ image2.src = objectURL2;
+ document.body.appendChild(image1);
+ document.body.appendChild(image2);
+
+ // Display the text in a paragraph
+ let para = document.createElement('p');
+ para.textContent = descText;
+ document.body.appendChild(para);
+});</pre>
+
+<h3 id="Pitfalls_6">Pitfalls</h3>
+
+<ul>
+ <li>If a <code>Promise.all()</code> rejects, then one or more of the promises you are feeding into it inside its array parameter must be rejecting, or might not be returning promises at all. You need to check each one to see what they returned. </li>
+</ul>
+
+<h3 id="Browser_compatibility_6">Browser compatibility</h3>
+
+<p>{{Compat("javascript.builtins.Promise.all")}}</p>
+
+<h3 id="Further_information_6">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises#Running_code_in_response_to_multiple_promises_fulfilling">Running code in response to multiple promises fulfilling</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all() reference</a></li>
+</ul>
+
+<h2 id="Asyncawait">Async/await</h2>
+
+<p>Syntactic sugar built on top of promises that allows you to run asynchronous operations using syntax that's more like writing synchronous callback code.</p>
+
+<table class="standard-table">
+ <caption>Useful for...</caption>
+ <thead>
+ <tr>
+ <th scope="col">Single delayed operation</th>
+ <th scope="col">Repeating operation</th>
+ <th scope="col">Multiple sequential operations</th>
+ <th scope="col">Multiple simultaneous operations</th>
+ </tr>
+ <tr>
+ <td>No</td>
+ <td>No</td>
+ <td>Yes</td>
+ <td>Yes (in combination with <code>Promise.all()</code>)</td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Code_example_7">Code example</h3>
+
+<p>The following example is a refactor of the simple promise example we saw earlier that fetches and displays an image, written using async/await (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/simple-refactored-fetch.html">see it live</a>, and see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/simple-refactored-fetch.html">source code</a>):</p>
+
+<pre class="brush: js notranslate">async function myFetch() {
+ let response = await fetch('coffee.jpg');
+ let myBlob = await response.blob();
+
+ let objectURL = URL.createObjectURL(myBlob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}
+
+myFetch();</pre>
+
+<h3 id="Pitfalls_7">Pitfalls</h3>
+
+<ul>
+ <li>You can't use the <code>await</code> operator inside a non-<code>async</code> function, or in the top level context of your code. This can sometimes result in an extra function wrapper needing to be created, which can be slightly frustrating in some circumstances. But it is worth it most of the time.</li>
+ <li>Browser support for async/await is not as good as that for promises. If you want to use async/await but are concerned about older browser support, you could consider using the <a href="https://babeljs.io/">BabelJS</a> library — this allows you to write your applications using the latest JavaScript and let Babel figure out what changes if any are needed for your user’s browsers.</li>
+</ul>
+
+<h3 id="Browser_compatibility_7">Browser compatibility</h3>
+
+<p>{{Compat("javascript.statements.async_function")}}</p>
+
+<h3 id="Further_information_7">Further information</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">Async function reference</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">Await operator reference</a></li>
+</ul>
+
+<p>{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">General asynchronous programming concepts</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
diff --git a/files/pt-br/learn/javascript/asynchronous/index.html b/files/pt-br/learn/javascript/asynchronous/index.html
new file mode 100644
index 0000000000..67c3f8e466
--- /dev/null
+++ b/files/pt-br/learn/javascript/asynchronous/index.html
@@ -0,0 +1,67 @@
+---
+title: JavaScript Assíncrono
+slug: Learn/JavaScript/Asynchronous
+tags:
+ - Beginner
+ - CodingScripting
+ - Guide
+ - Guía
+ - Iniciante
+ - JavaScript
+ - Landing
+ - NeedsTranslation
+ - Promises
+ - TopicStub
+ - async
+ - asynchronous
+ - await
+ - callbacks
+ - requestAnimationFrame
+ - setInterval
+ - setTimeout
+translation_of: Learn/JavaScript/Asynchronous
+---
+<div>{{LearnSidebar}}</div>
+
+
+
+<div><span class="seoSummary">Neste módulo vamos entender {{Glossary("JavaScript")}} <a href="/pt-BR/docs/Glossario/Assincrono">Assíncrono</a></span><span class="seoSummary">, porque isso é importante e como pode ser usado para lidar com operações potencialmente bloqueantes, como a busca de recursos em um servidor remoto.</span></div>
+
+<h2 id="Pre_requisitos">Pre requisitos</h2>
+
+<p>Javascript Assíncrono é um tópico razoavelmente avançado e é aconselhada a leitura dos módulos <a href="/pt-BR/docs/Learn/JavaScript/First_steps">Primeiros Passos com Javascript</a> e <a href="/pt-BR/docs/Aprender/JavaScript/Elementos_construtivos">Elementos construtivos do Javascript</a> antes de continuar.</p>
+
+<p>Se você não estiver familiarizado com os conceitos de programação assíncrona, a sugestão é iniciar com o artigo <a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Conceitos">Conceitos gerais da programação assíncrona</a> desse módulo. Caso contrário, você pode provavelmente pular para o módulo <a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Introdu%C3%A7%C3%A3o">Introdução ao Javascript Assíncrono</a>.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Se você está estudando a partir de um computador/tablet/ outro dispositivo onde não é capaz de criar seus próprios arquivos, é possível executar os códigos de exemplo (a maioria deles) em plataformas como <a href="http://jsbin.com/">JSBin</a> ou  <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Guias">Guias</h2>
+
+<dl>
+ <dt><a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Conceitos">Conceitos gerais da programação assíncrona</a></dt>
+ <dd>
+ <p>Nesse artigo vamos explorar um número de conceitos importantes relacionados à programação assíncrona e como aparece nos browsers Web. Você deve entender estes conceitos antes de seguir adiante através dos outros artigos neste módulo.</p>
+ </dd>
+ <dt><a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Introdu%C3%A7%C3%A3o">Introdução ao Javascript Assíncrono</a></dt>
+ <dd>Nesse artigo vamos recapitular brevemente os problemas associados ao Javascript síncrono e introduzir algumas das diferentes técnicas do Javascript assícrono que irá encontrar mais a frente, mostrando como essas técnicas podem nos ajudar a resolver tais problemas.</dd>
+ <dt><a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Javascript assícrono cooperativo: Timeouts e intervalos</a></dt>
+ <dd>Aqui contemplamos os métodos tradicionais que o Javascript possui disponível para executar código de forma assíncrona após decorrido um certo periodo de tempo ou em um intervalo regular (e.g. um determinado número de vezes por segundo), discutir sua utilidade e perceber alguns problemas inerentes a eles.</dd>
+ <dt><a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Promises">Manipulando elegantemente operações assíncronas com Promises</a></dt>
+ <dd>Promises são um novo recurso da linguagem Javascript que permitem adiar ações até que a ação anterior esteja concluída ou responder com falha. Isso é extremamente útil para montar uma sequência de operações para que funcione corretamente. Este artigo lhe orienta como as Promises funcionam, onde verá elas sendo utilizadas em <a href="/pt-BR/docs/WebAPI">WebAPIs</a>. Também aprenderá como escrever suas próprias promises.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Facilitando a programação assícrona com async e await</a></dt>
+ <dd>Promises podem ser um pouco complexas de construir e entender. Por esse motivo, os navegadores modernos implementado funções <code>async</code> e o operador <code>await.</code> O primeiro permite que funções padrão se comportem implicitamente de forma assíncrona com promises, enquanto que o último pode ser usado dentro de funções <code>async</code> para esperar por 'promessas' antes que a função continue. Isso faz com que o encadeamento de 'promessas' seja mais fácil de ler.</dd>
+ <dt><a href="/pt-BR/docs/Learn/JavaScript/Asynchronous/Escolhendo_abordagem_correta">Escolhendo a abordagem correta</a></dt>
+ <dd>Para concluir este módulo, vamos considerar as diferentes técnicas de programação e as features que abordamos do começo ao fim, considerando quais e quando utilizar, com recomendações e advertências das armadilhas mais comuns.</dd>
+</dl>
+
+<h2 id="Veja_Também">Veja Também</h2>
+
+<ul>
+ <li><a href="https://eloquentjavascript.net/11_async.html">Programação Assícrona</a> do livro online <a href="https://eloquentjavascript.net/">Eloquent JavaScript</a>, por Marijn Haverbeke.</li>
+</ul>
+
+<div class="note">
+<p><strong>Nota do tradutor</strong>: A segunda edição do <em>Eloquent Javascript</em> foi traduzida pela comunidade brasileira do Javascript e está disponível em <a href="https://github.com/braziljs/eloquente-javascript">Javascript Eloquente - 2ª Edição</a>. Até o momento da tradução deste artigo, a comunidade está trabalhando na conclusão da 3ª edição.</p>
+</div>
diff --git a/files/pt-br/learn/javascript/asynchronous/introdução/index.html b/files/pt-br/learn/javascript/asynchronous/introdução/index.html
new file mode 100644
index 0000000000..b95a88d35c
--- /dev/null
+++ b/files/pt-br/learn/javascript/asynchronous/introdução/index.html
@@ -0,0 +1,283 @@
+---
+title: Introdução ao JavaScript Async
+slug: Learn/JavaScript/Asynchronous/Introdução
+translation_of: Learn/JavaScript/Asynchronous/Introducing
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}</div>
+
+<div>Neste artigo nós recapitulamos brevemente os problemas que são associados com o JavaScript síncrono, e dar  uma primeira olhada em algumas das diferentes técnicas assíncronas que você vai encontrar, mostrando como elas podem nos ajudar a resolver tais problemas.</div>
+
+<div></div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Conhecimentos básicos de informática e sobre os fundamentos do JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Ganhar familiaridade com o que é o Js assíncrono e como ele se difere do Js síncrono.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="JavaScript_síncrono">JavaScript síncrono</h2>
+
+<p>Para entendermos o que é o <strong>{{Glossary("asynchronous")}}</strong> JavaScript, nós primeiro temos que ter certeza que entedemos o que é o <strong>{{Glossary("synchronous")}}</strong> JavaScript. Essa seção revê um pouco das informações que nós vimos no artigo anterior.</p>
+
+<p>Muitas das funcionalidades que nós vimos em áreas anteriores são síncronas — você executa um código, e o reultado é retornado assim que o navegador puder. Vamos ver um exemplo simples (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/basic-function.html">veja aqui</a>, e <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/basic-function.html">veja o código fonte</a>):</p>
+
+<pre class="brush: js">const btn = document.querySelector('button');
+btn.addEventListener('click', () =&gt; {
+ alert('Você clicou em mim!');
+
+ let pElem = document.createElement('p');
+ pElem.textContent = 'Este é um novo parágrafo adicionado';
+ document.body.appendChild(pElem);
+});
+</pre>
+
+<p>Neste bloco, as linhas são executadas uma após a outra:</p>
+
+<ol>
+ <li>Nós damos referência à um elemento {{htmlelement("button")}} que já está disponível na DOM.</li>
+ <li>Nós adicionamos um evento de <code><a href="/en-US/docs/Web/API/Element/click_event">click</a></code>, e quando ele for clicado ele fará o seguinte:
+ <ol>
+ <li>Mostrar uma mensagem no <code><a href="/en-US/docs/Web/API/Window/alert">alert()</a></code>.</li>
+ <li>Uma vez que o alert for dispensado, nós criamos um elemento {{htmlelement("p")}}.</li>
+ <li>Depois nós o preenchemos com um texto.</li>
+ <li>E finalmente, o adicionamos no body.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Enquanro cada operação é processada, nada mais pode acontecer — a renderização é pausada. Isso acontece porque o JavaScript opera em uma única thread (<a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts#JavaScript_is_single_threaded">JavaScript é single threaded</a>). Apenas uma coisa pode acontecer por vez, em uma única thread principal, e tudo é bloqueado até que a operação seja concluída.</p>
+
+<p>Então, no exemplo acima, depois que você tenha clicado no botão, o parágrafo não vai aparecer até que o botão OK do alert seja pressionado. Tente isso com o botão a seguir:</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;<span class="pl-ent">button</span>&gt;Clique em mim&lt;/<span class="pl-ent">button</span>&gt;</pre>
+</div>
+
+<p>{{EmbedLiveSample('Synchronous_JavaScript', '100%', '70px')}}</p>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: É importante lembrar que, mesmo sendo muito útil para demonstar uma situação de blocking, o <code><a href="/en-US/docs/Web/API/Window/alert">alert()</a></code> não é de bom uso em aplicativos reais.</p>
+</div>
+
+<h2 id="Asynchronous_JavaScript">Asynchronous JavaScript</h2>
+
+<p>Por razões esclarecidas anteriormente (e.g. relativas ao blocking), muitas funcionalidades de APIs da Web agora usam código assíncrono na execução, especialmente aquelas que acessam ou buscam algum tipo de recurso de um dispositivo externo, como pegar um arquivo da rede, acessar um banco de dados e retornar dados dele, acessar uma stream de uma web cam, ou transmitir uma tela para um dispositivo VR.</p>
+
+<p>Por que é tão difícil trabalhar com isso usando códigos síncronos? Vamos dar uma olhada em um exemplo rápido. Quando você pega uma imagem de um servidor, você não pode retornar o resultado imediatamente. Isso significa que o pseudocódigo a seguir não poderia funcionar:</p>
+
+<pre class="brush: js">let resposta = fetch('myImage.png');
+let blob = resposta.blob();
+// Mostra sua imagem na UI</pre>
+
+<p>Isso acontece por que você não sabe quanto tempo a imagem levará para ser baixada, então quando você executar a segunda linha, ela vai resultar em um erro (provalvelmente sempre) porque a  <code>resposta</code> não estará disponível ainda. Você precisa que o seu código espere até que a <code>resposta</code> seja retornada antes de fazer algo com ela.</p>
+
+<p>Existem dois tipos principais de estilo de código assíncrono que você encontrará no código JavaScript, as callbacks com um estilo old-school e código em um estilo das promises mais recente. Nas seções abaixo, revisaremos cada um deles por vez.</p>
+
+<h2 id="Callbacks_assíncronas">Callbacks assíncronas</h2>
+
+<p>Callback são funções que são passada como parâmetros na chamada de outra função que vai executar código por trás do panos. Quando esse código por trás dos panos terminar de ser executado, a função callback será chamada para te informar que a tarefa foi finalizada ou que algo do seu interesse aconteceu. O uso das callbacks é um pouco antiquado agora, mas você ainda pode vê-las em um número de APIs comumente usadas.</p>
+
+<p>Um exemplo de uma callback async é o segundo parâmetro do método {{domxref("EventTarget.addEventListener", "addEventListener()")}} (como vimos em ação anteriormente):</p>
+
+<pre class="brush: js">btn.addEventListener('click', () =&gt; {
+ alert('Você clicou em mim!');
+
+ let pElem = document.createElement('p');
+ pElem.textContent = 'Este é um novo parágrafo.';
+ document.body.appendChild(pElem);
+});</pre>
+
+<p>O primeiro parâmetro é o tipo de evento a ser executado e o segundo parâmetro é uma função callback que é chamada quando o evento é disparado.</p>
+
+<p>Quando passamos uma função callback como um parâmetro em outra função, nós apenas estamos passando a rêferencia da função como argumento, ou seja, a função callback <strong>não</strong><strong> é</strong> executada imediatamente. Ela é chamada de volta assíncronamente dentro do corpo da função que a contém, que é responsável por executar a função callback quando for necessário.</p>
+
+<p>Você pode escrever a sua própria função que contém uma callback facilmente. Vamos dar uma olhada em outro exemplo que carrega uma arquivo usando a <a href="/en-US/docs/Web/API/XMLHttpRequest">API <code>XMLHttpRequest</code> </a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/xhr-async-callback.html">veja aqui</a>, and <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/xhr-async-callback.html">veja o código fonte</a>):</p>
+
+<pre class="brush: js">function loadAsset(url, type, callback) {
+ let xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = type;
+
+ xhr.onload = function() {
+ callback(xhr.response);
+ };
+
+ xhr.send();
+}
+
+function displayImage(blob) {
+ let objectURL = URL.createObjectURL(blob);
+
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);</pre>
+
+<p>Aqui nós criamos uma função <code>displayImage()</code> que simplesmente representa um blob que foi passada à ela como uma URL de objeto, e depois cria uma imagem para mostrar a URL, adicionando-a ao <code>&lt;body&gt;</code> do documento. Entretando, nós criamos depois uma função <code>loadAsset()</code> que pega uma callback como parâmetro, junto com uma URL a ser buscada e um tipo para o conteúdo. Ela usa o <code>XMLHttpRequest</code> (abreviação: "XHR") para buscar o recurso na URL dada, para depois passar a resposta para a callback para fazer algo com isso. Neste caso a callback está esperando o XHR  terminar de baixar o recurso (usando o manipulador de eventos <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) antes de passá-lo para a callback.</p>
+
+<p>Callback são versáteis — elas não apenas lhe permitem controlar a ordem em que as funções são executadas e quais dados são passados entre elas, elas também podem passar dados para diferentes funçoes dependendo das circunstâncias. Então você pode ter ações diferentes para executar na resposta baixada, como <code>processJSON()</code>, <code>displayText()</code>, etc.</p>
+
+<p>Note que nem todas as callback são assíncronas — algumas são executadas de um modo síncrono. Um exemplo é quando nós usamos o método {{jsxref("Array.prototype.forEach()")}} para iterar sobre os itens de uma array (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/foreach.html">veja aqui</a>, e a <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/foreach.html">fonte</a>):</p>
+
+<pre class="brush: js">const gods = ['Apollo', 'Artemis', 'Ares', 'Zeus'];
+
+gods.forEach(function (eachName, index){
+ console.log(index + '. ' + eachName);
+});</pre>
+
+<p>Neste exemplo nós iteramos sobra uma array de Deuses Gregos e imprimos o índice e seus valores no console. O parâmetro de <code>forEach()</code> é uma callback function, que por si só toma dois parâmetros: uma refêrencia ao nome da array e e os valores dos índices. Entretanto, ela não espera por algo para fazer a execução, pois isso acontece imediatamente</p>
+
+<h2 id="Promises">Promises</h2>
+
+<p>Promises são uma nova maneira de escrever código assíncrono que você verá em APIs Web modernas. Um bom exemplo disso é a API <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a></code>, que é basicamente uma versão mais moderna e eficiente de {{domxref("XMLHttpRequest")}}. Vamos dar uma olhada em um exemplo rápido, do nosso artigo de <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Pegando dados do servidor</a>:</p>
+
+<pre class="brush: js">fetch('products.json').then(function(response) {
+  return response.json();
+}).then(function(json) {
+  products = json;
+  initialize();
+}).catch(function(err) {
+  console.log('Fetch problem: ' + err.message);
+});</pre>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: Você pode encontrar a versão finalizada no GitHub (<a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store-xhr/can-script.js">veja aqui</a>, e também <a href="https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store-xhr/">seja a execução</a>).</p>
+</div>
+
+<p>Aqui nós vemos <code>fetch</code><code>()</code> pegando um único parâmetro — a URL de um recurso que você quer pegar da rede — e retornando uma <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promise</a>. A promise é um objeto que representa a conclusão ou falha da operação assíncrona. Ela represente um estado intermediário, por assim dizer. É praticamente o jetio do navegador de dizer "Eu prometo voltar para você com a resposta o mais rápido possível", daí o nome "promessa".</p>
+
+<p>Você pode levar um tempo para se acostumar com esse conceito; Ele se parece um pouco com o {{interwiki("wikipedia", "Gato de Schrödinger")}} em ação. Nenhum dos possíveis resultados aconteceu ainda, então a operação fetch está esperando pelo resultado do navegador que vai completar a operação em algum ponto no futuro.</p>
+
+<p>Nós temos três blocos de código encadeados ao fim do <code>fetch()</code>:</p>
+
+<ul>
+ <li>Dois blocos <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code>. Ambos contém uma função callback que será executada se a operação anterior for executada, então você pode fazer algo com o resultado. Cada bloco <code>.then()</code> retorna outra promise, o que significa que você pode encadear múltiplos blocos <code>.then()</code> um ao outro, para que múltiplas operações assíncronas possam ser executadas uma atrás da outra.</li>
+ <li>O bloco <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">catch()</a></code> no final será executado em casos em que erros ocorrem quando um dos <code>.then()</code> falhe — de um modo similar aos blocos <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code> síncronos, um objeto de erro fica disponível dentro do <code>catch()</code>, e pode ser usado para reportar erros que ocorreram. Note que o bloco <code>try...catch</code> não funcionará com promises, embora funcione com <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">async/await</a>, como você aprenderá mais adiante.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: Você vai aprender mais sobre promises mais tarde no módulo, então não se preocupe se você não entendeu muito bem.</p>
+</div>
+
+<h3 id="A_fila_de_eventos">A fila de eventos</h3>
+
+<p>Operações assíncronas como as promises são colocadas em uma <strong>fila de eventos</strong>, que é executada depois que a main thread terminar de ser processada. As operações serão completadas assim que for possível e depois retornam seus resultados para o ambiente JavaScript.</p>
+
+<h3 id="Promises_versus_callbacks">Promises versus callbacks</h3>
+
+<p>As promises tem algumas semelhanças com as callbacks. Elas são basicamente um objeto retornado em que você vincula funções callback, ao invés de passar as callbacks para uma função.</p>
+
+<p>Entretanto, as promises são feitas especificamente para lidarmos com operações async, e ter muitas vantagens sobre as velhas callbacks:</p>
+
+<ul>
+ <li>Você pode encadear múltiplas operações assíncronas usando múltiplos blocos <code>.then()</code>, passando o resultado de uma delas como o resultado como parâmetro da próxima operação. Isso é muito mais difícil de se fazer usando as callback, que normalmente termina em algo chamado de <a href="http://callbackhell.com/">callback hell</a>.</li>
+ <li>As callbacks das promises sempre são chamadas na ordem estrita em quesão colocadas na fila de eventos.</li>
+ <li>O tratamento de erros é muito melhor — todos os erros são tratados por um único bloco <code>.catch()</code> no final do encadeamento, ao invés de ser tratado individualmente em cada função callback.</li>
+ <li>Promessas evitam inversão de controle. Ao contrário das callbacks, que perdem totalmente o controle de como a função será executada quando passada para uma biblioteca de terceiros.</li>
+</ul>
+
+<h2 id="A_natureza_do_código_assíncrono">A natureza do código assíncrono</h2>
+
+<p>Vamos explorar um exemplo que ilustra a natureza do código assíncrono, mostrando o que pode acontecer quando nós não estamos cientes da ordem de execução e dos problemas em tentar tratar código async como código síncrono. O exemplo a seguir é muito similar ao que vimos antes (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/async-sync.html">veja aqui</a>, e <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync.html">a fonte</a>). Uma diferença e que nós icluimos um número de declarações {{domxref("console.log()")}} para ilustrar na ordem que você pensa que o código fosse executado.</p>
+
+<pre class="brush: js">console.log ('Starting');
+let image;
+
+fetch('coffee.jpg').then((response) =&gt; {
+ console.log('It worked :)')
+ return response.blob();
+}).then((myBlob) =&gt; {
+ let objectURL = URL.createObjectURL(myBlob);
+ image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}).catch((error) =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + error.message);
+});
+
+console.log ('All done!');</pre>
+
+<p>O navegador vai começar a executar o código, veja a primeira declaração <code>console.log()</code>(<code>Starting</code>) e a execute, e depois crie a variável <code>image</code>.</p>
+
+<p>Depois a segunda linha vai começar a ser executada começando com o bloco <code>fetch()</code>, mas desde que <code>fetch()</code> é executado assíncronamente sem bloquear nada, a execução do código continua mesmo depois do código promise, alcançando a última declaração <code>console.log()</code>(<code>All done!</code>) e imprimindo a no console.</p>
+
+<p>Uma vez que o bloco <code>fetch()</code> tenha terminado a sua execução e retornado seu resultado com os blocos <code>.then()</code>, nós finalmente veremos a segunda mensagem <code>console.log()</code> (<code>It worked :)</code>) appear. Então as mensagens aparecem nessa ordem:</p>
+
+<ul>
+ <li>Starting</li>
+ <li>All done!</li>
+ <li>It worked :)</li>
+</ul>
+
+<p>Se isso te deixa confuso, então considere o exemplo a seguir:</p>
+
+<pre class="brush: js">console.log("registering click handler");
+
+button.addEventListener('click', () =&gt; {
+ console.log("get click");
+});
+
+console.log("all done");</pre>
+
+<p>Isso é bem similar no comportamento — a primeira e a terceira mensagens <code>console.log()</code> são mostradas imediatamente, mas a segunda está bloqueada até alguém clique no botão. O exemplo anterior funciona da mesma forma, exceto que no caso a segunda mensagem está bloqueada na promise pegando um recurso e depois o mostra na tela.</p>
+
+<p>Em um exemplo mais superficial, esse tipo de configuração poderia causar um problema — você não pode incluir um bloco async que retorna um resultado, que depois depende de um código síncrono. Você não pode garantir que a função async vai retornar antes que o navegador processou o bloco síncrono.</p>
+
+<p>Para ver isso em ação, tente fazer uma cópia local do <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync.html">nosso exemplo</a>, e mudar o terceiro <code>console.log()</code> para o seguinte:</p>
+
+<pre class="brush: js">console.log ('Tudo Feito! ' + image.src + 'mostrada.');</pre>
+
+<p>Agora você deve ter um erro no seu console ao invés da terceira mensagem:</p>
+
+<pre><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body">TypeError: image is undefined; can't access its "src" property</span></span></span></pre>
+
+<p>Isso acontece porque o navegador tenta executar o terceiro <code>console.log()</code> e o bloco <code>fetch()</code> não terminou de ser executado e não foi dado  um valor para a variável <code>image</code>.</p>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>:Por razões de segurança, você não pode usar o <code>fetch()</code>  com arquivos do seu sistema local (ou executar operações localmente); para executar o exemplo acima você teria que rodá-lo em um <a href="/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server">servidor local</a>.</p>
+</div>
+
+<h2 id="Aprendizado_ativo_faça_tudo_async!">Aprendizado ativo: faça tudo async!</h2>
+
+<p>Faça que o exemplo problemático de <code>fetch()</code> imprima três mensagens <code>console.log()</code> na tela na ordem desejada, você pode fazer a útima declaração <code>console.log()</code> assíncrona também. Isso pode ser feito colocando ela em outro bloco <code>.then()</code> encadeamo no final do segundo bloco, ou por simplesmente movê-lo para dentro do segundo bloco <code>then()</code>.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you get stuck, you can <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync-fixed.html">find an answer here</a> (see it <a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/async-sync-fixed.html">running live</a> also). You can also find a lot more information on promises in our <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a> guide, later on in the module.</p>
+</div>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>In its most basic form, JavaScript is a synchronous, blocking, single-threaded language, in which only one operation can be in progress at a time. But web browsers define functions and APIs that allow us to register functions that should not be executed synchronously, and should instead be invoked asynchronously when some kind of event occurs (the passage of time, the user's interaction with the mouse, or the arrival of data over the network, for example). This means that you can let your code do several things at the same time without stopping or blocking your main thread.</p>
+
+<p>Whether we want to run code synchronously or asynchronously will depend on what we're trying to do.</p>
+
+<p>There are times when we want things to load and happen right away. For example when applying some user-defined styles to a webpage you'll want the styles to be applied as soon as possible.</p>
+
+<p>If we're running an operation that takes time however, like querying a database and using the results to populate templates, it is better to push this off the main thread and complete the task asynchronously. Over time, you'll learn when it makes more sense to choose an asynchronous technique over a synchronous one.</p>
+
+<ul>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">General asynchronous programming concepts</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
diff --git a/files/pt-br/learn/javascript/asynchronous/promises/index.html b/files/pt-br/learn/javascript/asynchronous/promises/index.html
new file mode 100644
index 0000000000..1fdd746d9d
--- /dev/null
+++ b/files/pt-br/learn/javascript/asynchronous/promises/index.html
@@ -0,0 +1,586 @@
+---
+title: Programação elegante com Promises
+slug: Learn/JavaScript/Asynchronous/Promises
+translation_of: Learn/JavaScript/Asynchronous/Promises
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p class="summary"><strong>Promises </strong>são uma nova implementação do JavaScript que permite você adiar ações até que determinada ação finalize. Isso é realmente bastante útil para uma sequência de operações assíncronas trabalharem corretamente. Neste artigo irá mostrar para você como Promises trabalham, como elas são usadas em web APIs e como escrever a sua Promise.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisitos:</th>
+ <td>Conhecimentos básicos em informática, um básico entendimento do JavaScript e seus fundamentos.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Entender promises e como elas funcionam.</td>
+ </tr>
+ </tbody>
+</table>
+
+
+
+<h2 id="O_que_são_promises">O que são promises?</h2>
+
+<p>Nós vimos apenas um resumo do que são <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> até agora, a partir daqui iremos explorar mais a fundo sobre elas.</p>
+
+<p>Essencialmente, uma Promise é um objeto que representa um estado intermediário de uma operação — de fato, uma <em>promessa</em> que  um resultado irá ser retornado em um ponto no futuro, mas isso não é garantia de que o resultado estará disponível, ou a promise falhará, o código será executado em ordem para fazer alguma coisa que o resultado seja sucesso, ou tratar uma falha.</p>
+
+<p>Generally you are less interested in the amount of time an async operation will take to return its result (unless of course it takes <em>far</em> too long!), and more interested in being able to respond to it being returned, whenever that is. And of course, it's nice that it doesn't block the rest of the code execution.</p>
+
+<p>One of the most common engagements you'll have with promises is with web APIs that return a promise. Let's consider a hypothetical video chat application. The application has a window with a list of the user's friends, and clicking on a button next to a user starts a video call to that user.</p>
+
+<p>That button's handler calls {{domxref("MediaDevices.getUserMedia", "getUserMedia()")}} in order to get access to the user's camera and microphone. Since <code>getUserMedia()</code> has to ensure that the user has permission to use those devices <em>and</em> ask the user which microphone to use and which camera to use (or whether to be a voice only call, among other possible options), it can block until not only all of those decisions are made, but also the camera and microphone have been engaged. In addition, the user may not respond immediately to these permission requests. This can potentially take a long time.</p>
+
+<p>Since the call to <code>getUserMedia()</code> is made from the browser's main thread, the entire browser is blocked until <code>getUserMedia()</code> returns! Obviously, that's not an acceptable option; without promises, everything in the browser becomes unusable until the user decides what to do about the camera and microphone. So instead of waiting for the user, getting the chosen devices enabled, and directly returning the {{domxref("MediaStream")}} for the stream created from the selected sources, <code>getUserMedia()</code> returns a {{jsxref("promise")}} which is resolved with the {{domxref("MediaStream")}} once it's available.</p>
+
+<p>The code that the video chat application would use might look something like this:</p>
+
+<pre class="brush: js notranslate">function handleCallButton(evt) {
+ setStatusMessage("Calling...");
+ navigator.mediaDevices.getUserMedia({video: true, audio: true})
+ .then(chatStream =&gt; {
+ selfViewElem.srcObject = chatStream;
+ chatStream.getTracks().forEach(track =&gt; myPeerConnection.addTrack(track, chatStream));
+ setStatusMessage("Connected");
+ }).catch(err =&gt; {
+ setStatusMessage("Failed to connect");
+ });
+}
+</pre>
+
+<p>This function starts by using a function called <code>setStatusMessage()</code> to update a status display with the message "Calling...", indicating that a call is being attempted. It then calls <code>getUserMedia()</code>, asking for a stream that has both video and audio tracks, then once that's been obtained, sets up a video element to show the stream coming from the camera as a "self view," then takes each of the stream's tracks and adds them to the <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC</a> {{domxref("RTCPeerConnection")}} representing a connection to another user. After that, the status display is updated to say "Connected".</p>
+
+<p>If <code>getUserMedia()</code> fails, the <code>catch</code> block runs. This uses <code>setStatusMessage()</code> to update the status box to indicate that an error occurred.</p>
+
+<p>The important thing here is that the <code>getUserMedia()</code> call returns almost immediately, even if the camera stream hasn't been obtained yet. Even if the <code>handleCallButton()</code> function has already returned to the code that called it, when <code>getUserMedia()</code> has finished working, it calls the handler you provide. As long as the app doesn't assume that streaming has begun, it can just keep on running.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note:</strong> You can learn more about this somewhat advanced topic, if you're interested, in the article <a href="/docs/Web/API/WebRTC_API/Signaling_and_video_calling">Signaling and video calling</a>. Code similar to this, but much more complete, is used in that example.</p>
+</div>
+
+<h2 id="The_trouble_with_callbacks">The trouble with callbacks</h2>
+
+<p>To fully understand why promises are a good thing, it helps to think back to old-style callbacks, and to appreciate why they are problematic.</p>
+
+<p>Let's talk about ordering pizza as an analogy. There are certain steps that you have to take for your order to be successful, which don't really make sense to try to execute out of order, or in order but before each previous step has quite finished:</p>
+
+<ol>
+ <li>You choose what toppings you want. This can take a while if you are indecisive, and may fail if you just can't make up your mind, or decide to get a curry instead.</li>
+ <li>You then place your order. This can take a while to return a pizza, and may fail if the restaurant does not have the required ingredients to cook it.</li>
+ <li>You then collect your pizza and eat. This might fail if, say, you forgot your wallet so can't pay for the pizza!</li>
+</ol>
+
+<p>With old-style <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing#Callbacks">callbacks</a>, a pseudo-code representation of the above functionality might look something like this:</p>
+
+<pre class="brush: js notranslate">chooseToppings(function(toppings) {
+ placeOrder(toppings, function(order) {
+ collectOrder(order, function(pizza) {
+ eatPizza(pizza);
+ }, failureCallback);
+ }, failureCallback);
+}, failureCallback);</pre>
+
+<p>This is messy and hard to read (often referred to as "callback hell"), requires the <code>failureCallback()</code> to be called multiple times (once for each nested function), with other issues besides.</p>
+
+<h3 id="Improvements_with_promises">Improvements with promises</h3>
+
+<p>Promises make situations like the above much easier to write, parse, and run. If we represented the above pseudo-code using asynchronous promises instead, we'd end up with something like this:</p>
+
+<pre class="brush: js notranslate">chooseToppings()
+.then(function(toppings) {
+ return placeOrder(toppings);
+})
+.then(function(order) {
+ return collectOrder(order);
+})
+.then(function(pizza) {
+ eatPizza(pizza);
+})
+.catch(failureCallback);</pre>
+
+<p>This is much better — it is easier to see what is going on, we only need a single <code>.catch()</code> block to handle all the errors, it doesn't block the main thread (so we can keep playing video games while we wait for the pizza to be ready to collect), and each operation is guaranteed to wait for previous operations to complete before running. We're able to chain multiple asynchronous actions to occur one after another this way because each <code>.then()</code> block returns a new promise that resolves when the <code>.then()</code> block is done running. Clever, right?</p>
+
+<p>Using arrow functions, you can simplify the code even further:</p>
+
+<pre class="brush: js notranslate">chooseToppings()
+.then(toppings =&gt;
+ placeOrder(toppings)
+)
+.then(order =&gt;
+ collectOrder(order)
+)
+.then(pizza =&gt;
+ eatPizza(pizza)
+)
+.catch(failureCallback);</pre>
+
+<p>Or even this:</p>
+
+<pre class="brush: js notranslate">chooseToppings()
+.then(toppings =&gt; placeOrder(toppings))
+.then(order =&gt; collectOrder(order))
+.then(pizza =&gt; eatPizza(pizza))
+.catch(failureCallback);</pre>
+
+<p>This works because with arrow functions <code>() =&gt; x</code> is valid shorthand for <code>() =&gt; { return x; }</code>.</p>
+
+<p>You could even do this, since the functions just pass their arguments directly, so there isn't any need for that extra layer of functions:</p>
+
+<pre class="brush: js notranslate">chooseToppings().then(placeOrder).then(collectOrder).then(eatPizza).catch(failureCallback);</pre>
+
+<p>This is not quite as easy to read, however, and this syntax might not be usable if your blocks are more complex than what we've shown here.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: You can make further improvements with <code>async</code>/<code>await</code> syntax, which we'll dig into in the next article.</p>
+</div>
+
+<p>At their most basic, promises are similar to event listeners, but with a few differences:</p>
+
+<ul>
+ <li>A promise can only succeed or fail once. It cannot succeed or fail twice and it cannot switch from success to failure or vice versa once the operation has completed.</li>
+ <li>If a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called, even though the event took place earlier.</li>
+</ul>
+
+<h2 id="Explaining_basic_promise_syntax_A_real_example">Explaining basic promise syntax: A real example</h2>
+
+<p>Promises are important to understand because most modern Web APIs use them for functions that perform potentially lengthy tasks. To use modern web technologies you'll need to use promises. Later on in the chapter we'll look at how to write your own promise, but for now we'll look at some simple examples that you'll encounter in Web APIs.</p>
+
+<p>In the first example, we'll use the <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a></code> method to fetch an image from the web, the {{domxref("Body.blob", "blob()")}} method to transform the fetch response's raw body contents into a {{domxref("Blob")}} object, and then display that blob inside an {{htmlelement("img")}} element. This is very similar to the example we looked at in the <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing#Asynchronous_JavaScript">first article of the series</a>, but we'll do it a bit differently as we get you building your own promise-based code.</p>
+
+<ol>
+ <li>
+ <p>First of all, download our <a href="https://github.com/mdn/learning-area/blob/master/html/introduction-to-html/getting-started/index.html">simple HTML template</a> and the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/coffee.jpg">sample image file</a> that we'll fetch.</p>
+ </li>
+ <li>
+ <p>Add a {{htmlelement("script")}} element at the bottom of the HTML {{htmlelement("body")}}.</p>
+ </li>
+ <li>
+ <p>Inside your {{HTMLElement("script")}} element, add the following line:</p>
+
+ <pre class="brush: js notranslate">let promise = fetch('coffee.jpg');</pre>
+
+ <p>This calls the <code>fetch()</code> method, passing it the URL of the image to fetch from the network as a parameter. This can also take an options object as a optional second parameter, but we are just using the simplest version for now. We are storing the promise object returned by <code>fetch()</code> inside a variable called <code>promise</code>. As we said before, this object represents an intermediate state that is initially neither success or failure — the official term for a promise in this state is <strong>pending</strong>.</p>
+ </li>
+ <li>
+ <p>To respond to the successful completion of the operation whenever that occurs (in this case, when a {{domxref("Response")}} is returned), we invoke the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">.then()</a></code> method of the promise object. The callback inside the <code>.then()</code> block (referred to as the <strong>executor</strong>) runs only when the promise call completes successfully and returns the {{domxref("Response")}} object — in promise-speak, when it has been <strong>fulfilled</strong>. It is passed the returned {{domxref("Response")}} object as a parameter.</p>
+
+ <div class="blockIndicator note">
+ <p><strong>Note</strong>: The way that a <code>.then()</code> block works is similar to when you add an event listener to an object using <code>AddEventListener()</code>. It doesn't run until an event occurs (when the promise fulfills). The most notable difference is that a .then() will only run once for each time it is used, whereas an event listener could be invoked multiple times.</p>
+ </div>
+
+ <p>We immediately run the <code>blob()</code> method on this response to ensure that the response body is fully downloaded, and when it is available transform it into a <code>Blob</code> object that we can do something with. The result of this is returned like so:</p>
+
+ <pre class="brush: js notranslate">response =&gt; response.blob()</pre>
+
+ <p>which is shorthand for</p>
+
+ <pre class="brush: js notranslate">function(response) {
+ return response.blob();
+}</pre>
+
+ <p>OK, enough explanation for now. Add the following line below your first line of JavaScript.</p>
+
+ <pre class="brush: js notranslate">let promise2 = promise.then(response =&gt; response.blob());</pre>
+ </li>
+ <li>
+ <p>Each call to <code>.then()</code> creates a new promise. This is very useful; because the <code>blob()</code> method also returns a promise, we can handle the <code>Blob</code> object it returns on fulfillment by invoking the <code>.then()</code> method of the second promise. Because we want to do something a bit more complex to the blob than just run a single method on it and return the result, we'll need to wrap the function body in curly braces this time (otherwise it'll throw an error).</p>
+
+ <p>Add the following to the end of your code:</p>
+
+ <pre class="brush: js notranslate">let promise3 = promise2.then(myBlob =&gt; {
+
+})</pre>
+ </li>
+ <li>
+ <p>Now let's fill in the body of the executor function. Add the following lines inside the curly braces:</p>
+
+ <pre class="brush: js notranslate">let objectURL = URL.createObjectURL(myBlob);
+let image = document.createElement('img');
+image.src = objectURL;
+document.body.appendChild(image);</pre>
+
+ <p>Here we are running the {{domxref("URL.createObjectURL()")}} method, passing it as a parameter the <code>Blob</code> returned when the second promise fulfills. This will return a URL pointing to the object. Then we create an {{htmlelement("img")}} element, set its <code>src</code> attribute to equal the object URL and append it to the DOM, so the image will display on the page!</p>
+ </li>
+</ol>
+
+<p>If you save the HTML file you've just created and load it in your browser, you'll see that the image is displayed in the page as expected. Good work!</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: You will probably notice that these examples are somewhat contrived. You could just do away with the whole <code>fetch()</code> and <code>blob()</code> chain, and just create an <code>&lt;img&gt;</code> element and set its <code>src</code> attribute value to the URL of the image file, <code>coffee.jpg</code>. We did however pick this example because it demonstrates promises in a nice simple fashion, rather than for its real world appropriateness.</p>
+</div>
+
+<h3 id="Responding_to_failure">Responding to failure</h3>
+
+<p>There is something missing — currently there is nothing to explicitly handle errors if one of the promises fails (<strong>rejects</strong>, in promise-speak). We can add error handling by running the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">.catch()</a></code> method of the previous promise. Add this now:</p>
+
+<pre class="brush: js notranslate">let errorCase = promise3.catch(e =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + e.message);
+});</pre>
+
+<p>To see this in action, try misspelling the URL to the image and reloading the page. The error will be reported in the console of your browser's developer tools.</p>
+
+<p>This doesn't do much more than it would if you just didn't bother including the <code>.catch()</code> block at all, but think about it — this allows us to control error handling exactly how we want. In a real app, your <code>.catch()</code> block could retry fetching the image, or show a default image, or prompt the user to provide a different image URL, or whatever.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: You can see <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/simple-fetch.html">our version of the example live</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/simple-fetch.html">source code</a> also).</p>
+</div>
+
+<h3 id="Chaining_the_blocks_together">Chaining the blocks together</h3>
+
+<p>This is a very longhand way of writing this out; we've deliberately done this to help you understand what is going on clearly. As shown earlier on in the article, you can chain together <code>.then()</code> blocks (and also <code>.catch()</code> blocks). The above code could also be written like this (see also <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/simple-fetch-chained.html">simple-fetch-chained.html</a> on GitHub):</p>
+
+<pre class="brush: js notranslate">fetch('coffee.jpg')
+.then(response =&gt; response.blob())
+.then(myBlob =&gt; {
+ let objectURL = URL.createObjectURL(myBlob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+})
+.catch(e =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + e.message);
+});</pre>
+
+<p>Bear in mind that the value returned by a fulfilled promise becomes the parameter passed to the next <code>.then()</code> block's executor function.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: <code>.then()</code>/<code>.catch()</code> blocks in promises are basically the async equivalent of a <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code> block in sync code. Bear in mind that synchronous <code>try...catch</code> won't work in async code.</p>
+</div>
+
+<h2 id="Promise_terminology_recap">Promise terminology recap</h2>
+
+<p>There was a lot to cover in the above section, so let's go back over it quickly to give you a <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises#Promise_terminology_recap">short guide that you can bookmark</a> and use to refresh your memory in the future. You should also go over the above section again a few more time to make sure these concepts stick.</p>
+
+<ol>
+ <li>When a promise is created, it is neither in a success or failure state. It is said to be <strong>pending</strong>.</li>
+ <li>When a promise returns, it is said to be <strong>resolved</strong>.
+ <ol>
+ <li>A successfully resolved promise is said to be <strong>fulfilled</strong>. It returns a value, which can be accessed by chaining a <code>.then()</code> block onto the end of the promise chain. The executor function inside the <code>.then()</code> block will contain the promise's return value.</li>
+ <li>An unsuccessful resolved promise is said to be <strong>rejected</strong>. It returns a <strong>reason</strong>, an error message stating why the promise was rejected. This reason can be accessed by chaining a <code>.catch()</code> block onto the end of the promise chain.</li>
+ </ol>
+ </li>
+</ol>
+
+<h2 id="Running_code_in_response_to_multiple_promises_fulfilling">Running code in response to multiple promises fulfilling</h2>
+
+<p>The above example showed us some of the real basics of using promises. Now let's look at some more advanced features. For a start, chaining processes to occur one after the other is all fine, but what if you want to run some code only after a whole bunch of promises have <em>all</em> fulfilled?</p>
+
+<p>You can do this with the ingeniously named <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all()</a></code> static method. This takes an array of promises as an input parameter and returns a new <code>Promise</code> object that will fulfill only if and when <em>all</em> promises in the array fulfill. It looks something like this:</p>
+
+<pre class="brush: js notranslate">Promise.all([a, b, c]).then(values =&gt; {
+ ...
+});</pre>
+
+<p>If they all fulfill, then chained <code>.then()</code> block's executor function will be passed an array containing all those results as a parameter. If any of the promises passed to <code>Promise.all()</code> reject, the whole block will reject.</p>
+
+<p>This can be very useful. Imagine that we’re fetching information to dynamically populate a UI feature on our page with content. In many cases, it makes sense to receive all the data and only then show the complete content, rather than displaying partial information.</p>
+
+<p>Let's build another example to show this in action.</p>
+
+<ol>
+ <li>
+ <p>Download a fresh copy of our <a href="https://github.com/mdn/learning-area/blob/master/html/introduction-to-html/getting-started/index.html">page template</a>, and again put a <code>&lt;script&gt;</code> element just before the closing <code>&lt;/body&gt;</code> tag.</p>
+ </li>
+ <li>
+ <p>Download our source files (<a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/coffee.jpg">coffee.jpg</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/tea.jpg">tea.jpg</a>, and <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/description.txt">description.txt</a>), or feel free to substitute your own.</p>
+ </li>
+ <li>
+ <p>In our script we'll first define a function that returns the promises we want to send to <code>Promise.all()</code>. This would be easy if we just wanted to run the <code>Promise.all()</code> block in response to three <code>fetch()</code> operations completing. We could just do something like:</p>
+
+ <pre class="brush: js notranslate">let a = fetch(url1);
+let b = fetch(url2);
+let c = fetch(url3);
+
+Promise.all([a, b, c]).then(values =&gt; {
+ ...
+});</pre>
+
+ <p>When the promise is fulfilled, the <code>values</code> passed into the fullfillment handler would contain three <code>Response</code> objects, one for each of the <code>fetch()</code> operations that have completed.</p>
+
+ <p>However, we don't want to do this. Our code doesn't care when the <code>fetch()</code> operations are done. Instead, what we want is the loaded data. That means we want to run the <code>Promise.all()</code> block when we get back usable blobs representing the images, and a usable text string. We can write a function that does this; add the following inside your <code>&lt;script&gt;</code> element:</p>
+
+ <pre class="brush: js notranslate">function fetchAndDecode(url, type) {
+ return fetch(url).then(response =&gt; {
+ if (type === 'blob') {
+ return response.blob();
+ } else if (type === 'text') {
+ return response.text();
+ }
+ })
+ .catch(e =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + e.message);
+ });
+}</pre>
+
+ <p>This looks a bit complex, so let's run through it step by step:</p>
+
+ <ol>
+ <li>First of all we define the function, passing it a URL and a string representing the type of resource it is fetching.</li>
+ <li>Inside the function body, we have a similar structure to what we saw in the first example — we call the <code>fetch()</code> function to fetch the resource at the specified URL, then chain it onto another promise that returns the decoded (or "read") response body. This was always the <code>blob()</code> method in the previous example.</li>
+ <li>However, two things are different here:
+ <ul>
+ <li>First of all, the second promise we return is different depending on what the <code>type</code> value is. Inside the executor function we include a simple <code>if ... else if</code> statement to return a different promise depending on what type of file we need to decode (in this case we've got a choice of <code>blob</code> or <code>text</code>, but it would be easy to extend this to deal with other types as well).</li>
+ <li>Second, we have added the <code>return</code> keyword before the <code>fetch()</code> call. The effect this has is to run the entire chain and then run the final result (i.e. the promise returned by <code>blob()</code> or <code>text()</code>) as the return value of the function we've just defined. In effect, the <code>return</code> statements pass the results back up the chain to the top.</li>
+ </ul>
+ </li>
+ <li>
+ <p>At the end of the block, we chain on a <code>.catch()</code> call, to handle any error cases that may come up with any of the promises passed in the array to <code>.all()</code>. If any of the promises reject, the catch block will let you know which one had a problem. The <code>.all()</code> block (see below) will still fulfill, but just won't display the resources that had problems. If you wanted the <code>.all</code> to reject, you'd have to chain the <code>.catch()</code> block on to the end of there instead.</p>
+ </li>
+ </ol>
+
+ <p>The code inside the function body is async and promise-based, therefore in effect the entire function acts like a promise — convenient.</p>
+ </li>
+ <li>
+ <p>Next, we call our function three times to begin the process of fetching and decoding the images and text, and store each of the returned promises in a variable. Add the following below your previous code:</p>
+
+ <pre class="brush: js notranslate">let coffee = fetchAndDecode('coffee.jpg', 'blob');
+let tea = fetchAndDecode('tea.jpg', 'blob');
+let description = fetchAndDecode('description.txt', 'text');</pre>
+ </li>
+ <li>
+ <p>Next, we will define a <code>Promise.all()</code> block to run some code only when all three of the promises stored above have successfully fulfilled. To begin with, add a block with an empty executor inside the <code>.then()</code> call, like so:</p>
+
+ <pre class="brush: js notranslate">Promise.all([coffee, tea, description]).then(values =&gt; {
+
+});</pre>
+
+ <p>You can see that it takes an array containing the promises as a parameter. The executor will only run when all three promises resolve; when that happens, it will be passed an array containing the results from the individual promises (i.e. the decoded response bodies), kind of like [coffee-results, tea-results, description-results].</p>
+ </li>
+ <li>
+ <p>Last of all, add the following inside the executor. Here we use some fairly simple sync code to store the results in separate variables (creating object URLs from the blobs), then display the images and text on the page.</p>
+
+ <pre class="brush: js notranslate">console.log(values);
+// Store each value returned from the promises in separate variables; create object URLs from the blobs
+let objectURL1 = URL.createObjectURL(values[0]);
+let objectURL2 = URL.createObjectURL(values[1]);
+let descText = values[2];
+
+// Display the images in &lt;img&gt; elements
+let image1 = document.createElement('img');
+let image2 = document.createElement('img');
+image1.src = objectURL1;
+image2.src = objectURL2;
+document.body.appendChild(image1);
+document.body.appendChild(image2);
+
+// Display the text in a paragraph
+let para = document.createElement('p');
+para.textContent = descText;
+document.body.appendChild(para);</pre>
+ </li>
+ <li>
+ <p>Save and refresh and you should see your UI components all loaded, albeit in a not particularly attractive way!</p>
+ </li>
+</ol>
+
+<p>The code we provided here for displaying the items is fairly rudimentary, but works as an explainer for now.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you get stuck, you can compare your version of the code to ours, to see what it is meant to look like — <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/promise-all.html">see it live</a>, and see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-all.html">source code</a>.</p>
+</div>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you were improving this code, you might want to loop through a list of items to display, fetching and decoding each one, and then loop through the results inside <code>Promise.all()</code>, running a different function to display each one depending on what the type of code was. This would make it work for any number of items, not just three.</p>
+
+<p>In addition, you could determine what the type of file is being fetched without needing an explicit <code>type</code> property. You could for example check the {{HTTPHeader("Content-Type")}} HTTP header of the response in each case using <code><a href="/en-US/docs/Web/API/Headers/get">response.headers.get("content-type")</a></code>, and then react accordingly.</p>
+</div>
+
+<h2 id="Running_some_final_code_after_a_promise_fulfillsrejects">Running some final code after a promise fulfills/rejects</h2>
+
+<p>There will be cases where you want to run a final block of code after a promise completes, regardless of whether it fulfilled or rejected. Previously you'd have to include the same code in both the <code>.then()</code> and <code>.catch()</code> callbacks, for example:</p>
+
+<pre class="brush: js notranslate">myPromise
+.then(response =&gt; {
+ doSomething(response);
+ runFinalCode();
+})
+.catch(e =&gt; {
+ returnError(e);
+ runFinalCode();
+});</pre>
+
+<p>In more recent modern browsers, the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally">.finally()</a></code> method is available, which can be chained onto the end of your regular promise chain allowing you to cut down on code repetition and do things more elegantly. The above code can now be written as follows:</p>
+
+<pre class="brush: js notranslate">myPromise
+.then(response =&gt; {
+ doSomething(response);
+})
+.catch(e =&gt; {
+ returnError(e);
+})
+.finally(() =&gt; {
+ runFinalCode();
+});</pre>
+
+<p>For a real example, take a look at our <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/promise-finally.html">promise-finally.html demo</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-finally.html">source code</a> also). This works exactly the same as the <code>Promise.all()</code> demo we looked at in the above section, except that in the <code>fetchAndDecode()</code> function we chain a <code>finally()</code> call on to the end of the chain:</p>
+
+<pre class="brush: js notranslate">function fetchAndDecode(url, type) {
+ return fetch(url).then(response =&gt; {
+ if(type === 'blob') {
+ return response.blob();
+ } else if(type === 'text') {
+ return response.text();
+ }
+ })
+ .catch(e =&gt; {
+ console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
+ })
+ .finally(() =&gt; {
+ console.log(`fetch attempt for "${url}" finished.`);
+ });
+}</pre>
+
+<p>This logs a simple message to the console to tell us when each fetch attempt has finished.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: <code>finally()</code> allows you to write async equivalents to try/catch/finally in async code.</p>
+</div>
+
+<h2 id="Building_your_own_custom_promises">Building your own custom promises</h2>
+
+<p>The good news is that, in a way, you've already built your own promises. When you've chained multiple promises together with <code>.then()</code> blocks, or otherwise combined them to create custom functionality, you are already making your own custom async promise-based functions. Take our <code>fetchAndDecode()</code> function from the previous examples, for example.</p>
+
+<p>Combining different promise-based APIs together to create custom functionality is by far the most common way you'll do custom things with promises, and shows the flexibility and power of basing most modern APIs around the same principle. There is another way, however.</p>
+
+<h3 id="Using_the_Promise_constructor">Using the Promise() constructor</h3>
+
+<p>It is possible to build your own promises using the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise()</a></code> constructor. The main situation in which you'll want to do this is when you've got code based on an an old-school asynchronous API that is not promise-based, which you want to promis-ify. This comes in handy when you need to use existing, older project code, libraries, or frameworks along with modern promise-based code.</p>
+
+<p>Let's have a look at a simple example to get you started — here we wrap a <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code> call with a promise — this runs a function after two seconds that resolves the promise (using the passed <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve">resolve()</a></code> call) with a string of "Success!".</p>
+
+<pre class="brush: js notranslate">let timeoutPromise = new Promise((resolve, reject) =&gt; {
+ setTimeout(function(){
+ resolve('Success!');
+ }, 2000);
+});</pre>
+
+<p><code>resolve()</code> and <code>reject()</code> are functions that you call to fulfill or reject the newly-created promise. In this case, the promise fulfills with a string of "Success!".</p>
+
+<p>So when you call this promise, you can chain a <code>.then()</code> block onto the end of it and it will be passed a string of "Success!". In the below code we simply alert that message:</p>
+
+<pre class="brush: js notranslate">timeoutPromise
+.then((message) =&gt; {
+ alert(message);
+})</pre>
+
+<p>or even just</p>
+
+<pre class="brush: js notranslate">timeoutPromise.then(alert);
+</pre>
+
+<p>Try <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/custom-promise.html">running this live</a> to see the result (also see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/custom-promise.html">source code</a>).</p>
+
+<p>The above example is not very flexible — the promise can only ever fulfill with a single string, and it doesn't have any kind of <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject">reject()</a></code> condition specified (admittedly, <code>setTimeout()</code> doesn't really have a fail condition, so it doesn't matter for this simple example).</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Why <code>resolve()</code>, and not <code>fulfill()</code>? The answer we'll give you for now is <em>it's complicated</em>.</p>
+</div>
+
+<h3 id="Rejecting_a_custom_promise">Rejecting a custom promise</h3>
+
+<p>We can create a promise that rejects using the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject">reject()</a></code> method — just like <code>resolve()</code>, this takes a single value, but in this case it is the reason to reject with, i.e., the error that will be passed into the <code>.catch()</code> block.</p>
+
+<p>Let's extend the previous example to have some <code>reject()</code> conditions as well as allowing different messages to be passed upon success.</p>
+
+<p>Take a copy of the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/custom-promise.html">previous example</a>, and replace the existing <code>timeoutPromise()</code> definition with this:</p>
+
+<pre class="brush: js notranslate">function timeoutPromise(message, interval) {
+ return new Promise((resolve, reject) =&gt; {
+ if (message === '' || typeof message !== 'string') {
+ reject('Message is empty or not a string');
+ } else if (interval &lt; 0 || typeof interval !== 'number') {
+ reject('Interval is negative or not a number');
+ } else {
+ setTimeout(function(){
+ resolve(message);
+ }, interval);
+ }
+ });
+};</pre>
+
+<p>Here we are passing two methods into a custom function — a message to do something with, and the time interval to pass before doing the thing. Inside the function we then return a new <code>Promise</code> object — invoking the function will return the promise we want to use.</p>
+
+<p>Inside the Promise constructor, we do a number of checks inside <code>if ... else</code> structures:</p>
+
+<ol>
+ <li>First of all we check to see if the message is appropriate for being alerted. If it is an empty string or not a string at all, we reject the promise with a suitable error message.</li>
+ <li>Next, we check to see if the interval is an appropriate interval value. If it is negative or not a number, we reject the promise with a suitable error message.</li>
+ <li>Finally, if the parameters both look OK, we resolve the promise with the specified message after the specified interval has passed using <code>setTimeout()</code>.</li>
+</ol>
+
+<p>Since the <code>timeoutPromise()</code> function returns a <code>Promise</code>, we can chain <code>.then()</code>, <code>.catch()</code>, etc. onto it to make use of its functionality. Let's use it now — replace the previous <code>timeoutPromise</code> usage with this one:</p>
+
+<pre class="brush: js notranslate">timeoutPromise('Hello there!', 1000)
+.then(message =&gt; {
+ alert(message);
+})
+.catch(e =&gt; {
+ console.log('Error: ' + e);
+});</pre>
+
+<p>When you save and run the code as is, after one second you'll get the message alerted. Now try setting the message to an empty string or the interval to a negative number, for example, and you'll be able to see the promise reject with the appropriate error messages! You could also try doing something else with the resolved message rather than just alerting it.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: You can find our version of this example on GitHub as <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/custom-promise2.html">custom-promise2.html</a> (see also the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/custom-promise2.html">source code</a>).</p>
+</div>
+
+<h3 id="A_more_real-world_example">A more real-world example</h3>
+
+<p>The above example was kept deliberately simple to make the concepts easy to understand, but it is not really very async. The asynchronous nature is basically faked using <code>setTimeout()</code>, although it does still show that promises are useful for creating a custom function with sensible flow of operations, good error handling, etc.</p>
+
+<p>One example we'd like to invite you to study, which does show a useful async application of the <code>Promise()</code> constructor, is <a href="https://github.com/jakearchibald/idb/">Jake Archibald's idb library</a>. This takes the <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a>, which is an old-style callback-based API for storing and retrieving data on the client-side, and allows you to use it with promises. If you look at the <a href="https://github.com/jakearchibald/idb/blob/master/lib/idb.js">main library file</a> you'll see the same kind of techniques we discussed above being used there. The following block converts the basic request model used by many IndexedDB methods to use promises:</p>
+
+<pre class="brush: js notranslate">function promisifyRequest(request) {
+ return new Promise(function(resolve, reject) {
+ request.onsuccess = function() {
+ resolve(request.result);
+ };
+
+ request.onerror = function() {
+ reject(request.error);
+ };
+ });
+}</pre>
+
+<p>This works by adding a couple of event handlers that fulfill and reject the promise at appropriate times:</p>
+
+<ul>
+ <li>When the <code><a href="/en-US/docs/Web/API/IDBRequest">request</a></code>'s <a href="/en-US/docs/Web/API/IDBRequest/success_event"><code>success</code> event</a> fires, the <code><a href="/en-US/docs/Web/API/IDBRequest/onsuccess">onsuccess</a></code> handler fulfills the promise with the request <code><a href="/en-US/docs/Web/API/IDBRequest/result">result</a></code>.</li>
+ <li>When the <code><a href="/en-US/docs/Web/API/IDBRequest">request</a></code>'s <a href="/en-US/docs/Web/API/IDBRequest/error_event"><code>error</code> event</a> fires, the <code><a href="/en-US/docs/Web/API/IDBRequest/onerror">onerror</a></code> handler rejects the promise with the request <code><a href="/en-US/docs/Web/API/IDBRequest/error">error</a></code>.</li>
+</ul>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Promises are a good way to build asynchronous applications when we don’t know the return value of a function or how long it will take to return. They make it easier to express and reason about sequences of asynchronous operations without deeply nested callbacks, and they support a style of error handling that is similar to the synchronous <code>try...catch</code> statement.</p>
+
+<p>Promises work in the latest versions of all modern browsers; the only place where promise support will be a problem is in Opera Mini and IE11 and earlier versions.</p>
+
+<p>We didn't touch on all promise features in this article, just the most interesting and useful ones. As you start to learn more about promises, you'll come across further features and techniques.</p>
+
+<p>Most modern Web APIs are promise-based, so you'll need to understand promises to get the most out of them. Among those APIs are <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC</a>, <a href="/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>, <a href="/en-US/docs/Web/API/Media_Streams_API">Media Capture and Streams</a>, and many more. Promises will be more and more important as time goes on, so learning to use and understand them is an important step in learning modern JavaScript.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise()</a></code></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">Using promises</a></li>
+ <li><a href="https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">We have a problem with promises</a> by Nolan Lawson</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">General asynchronous programming concepts</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
diff --git a/files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html b/files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html
new file mode 100644
index 0000000000..2c399201e5
--- /dev/null
+++ b/files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html
@@ -0,0 +1,624 @@
+---
+title: Timeouts e intervalos
+slug: Learn/JavaScript/Asynchronous/Timeouts_and_intervals
+translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p class="summary">Este tutorial é sobre os métodos tradicionais que o JavaScript tem disponíveis para executar códigos assíncronamente depois que um dado período de tempo tenha passado, ou em um intervalo (um número de segundos por segundo), discute suas utilidades e considera seus problemas.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requisitos:</th>
+ <td>Entendimento básico sobre informáticas e fundamentos do JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objetivo:</th>
+ <td>Entender loops e intervalos assíncronos e para o que eles servem.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Introdução">Introdução</h2>
+
+<p>Por um longo tempo, a plataforma web tem oferecido à programadores JavaScript um número de funções que permitem que eles executem código assíncronamente depois de um determinado intervalo de tempo, e executar um bloco de código de modo assíncrono repetidamente até que você o mande parar.</p>
+
+<p>Essas funções são:</p>
+
+<dl>
+ <dt><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code></dt>
+ <dd>Executa um bloco específico uma vez depois de um determinado tempo</dd>
+ <dt><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code></dt>
+ <dd>Executa um bloco específico repetidamente com um intervalo fixo entre cada chamada.</dd>
+ <dt><code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code></dt>
+ <dd>Uma versão moderna de <code>setInterval()</code>. Ela executa um  bloc de código específico antes do navegador renderizar a tela novamento, permitindo que seja executada em uma taxa de quadros adequada, independentemente do ambiente em que está sendo executado.</dd>
+</dl>
+
+<p>O código executado por estas funções é executado na main thread (depois do dado intervalo).</p>
+
+<div>
+<p>É importante saber que você pode (e irá) executar outros códigos antes que uma chamada <code>setTimeout()</code> é executada, ou entre iterações de <code>setInterval()</code>. Dependendo de como essas operações são intensas, elas podem atrasar o seu código async ainda mais, já que o código async só é executado depois que a main thread terminar seu processamento (ou seja, quando a fila estiver vazia). Você aprenderá mais sobre isso enquanto fazemos nosso progresso neste artigo.</p>
+</div>
+
+<p>De qualquer forma, essas funções são usadas para executar animações constantes e outros processamentos em um web site ou aplicação. Nas seções a seguir, nós vamos te mostrar como elas podem ser usadas.</p>
+
+<h2 id="setTimeout">setTimeout()</h2>
+
+<p>Como foi dito anteriormente, o <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code> executa um bloco de código particular depois que um determinado período de tempo passou. Ele toma os seguintes parâmetros:</p>
+
+<ul>
+ <li>Uma função a ser executada, ou uma referência de uma função definida em outro lugar.</li>
+ <li>Um número representando o intervalo de tempo em milissegundos (1000 milissegundos equivalem a 1 segundo) para esperar antes de executar o código. Se você especificar um valor de 0 (ou simplesmente omitir o valor), a função será executada assim que possível (mas não imediatamente).</li>
+ <li>Zero ou mais valores que representam quaisquer parâmetros que você quiser passar para a função quando ela for executada.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>NOTA:</strong> O tempos especificafo <strong>não</strong> é o tempo garantido de execução, mas sim o tempo míniimo de execução. As callback que você passa para essas funções não podem ser executadas até que a main thread esteja vazia.</p>
+
+<p>Como consequência, códigos como <code>setTimeout(fn, 0)</code><em> </em>serão executados assim que a fila estiver vazia, <strong>não</strong> imediatamente. Se você executar código como <code>setTimeout(fn, 0)</code> e depois imediatamente executar um loop que conta de 1 a 10 bilhões, sua callback será executada depois de alguns segundos.</p>
+</div>
+
+<p>No exemplo a seguir, o navegador vai esperar dois segundos antes de executar a função anônima, e depois vai mostrar a mensagem de alerta (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">veja aqui</a>, e <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">veja o código</a>):</p>
+
+<pre class="brush: js notranslate">let myGreeting = setTimeout(function() {
+ alert('Hello, Mr. Universe!');
+}, 2000)</pre>
+
+<p>As funções especificadas não tem que  ser anônimas. Você pode dar o nome da função, e até mesmo definir ela em outro lugar e passar uma referência para o timeout <code>setTimeout()</code>. As versões a seguir do código são equivalentes à primeira:</p>
+
+<pre class="brush: js notranslate">// With a named function
+let myGreeting = setTimeout(function sayHi() {
+ alert('Hello, Mr. Universe!');
+}, 2000)
+
+// With a function defined separately
+function sayHi() {
+ alert('Hello Mr. Universe!');
+}
+
+let myGreeting = setTimeout(sayHi, 2000);</pre>
+
+<p>Isso pode ser útil se você tem uma função que precisa ser chamada de um timeout e também em resposta à um evento, por exemplo. Mas também pode servir para manter seu código organizado, especialmente se a callback timetout é mais do que algumas linhas de código.</p>
+
+<p><code>setTimeout()</code> retorna um valor identificador que pode ser usado para se referir ao timeout depois, como em quando você que pará-lo. Veja {{anch("Cancelando timetous")}} (abaixo) e aprenda como fazer isso.</p>
+
+<h3 id="Passando_parâmetros_para_uma_função_setTimeout">Passando parâmetros para uma função setTimeout()</h3>
+
+<p>Quaisquer parâmetros que você quiser passar para a função sendo executada dentro do <code>setTimeout()</code> devem ser passados como parâmetros adicionais no final da lista.</p>
+
+<p>Por exemplo, você pode mudar a função anterior para que ela diga oi para qualquer nome que foi passada para ela:</p>
+
+<pre class="brush: js notranslate">function sayHi(who) {
+ alert(`Hello ${who}!`);
+}</pre>
+
+<p>Agora, você pode passar o nome da pessoa no <code>setTimeout()</code> como um terceiro parâmetro:</p>
+
+<pre class="brush: js notranslate">let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');</pre>
+
+<h3 id="Cancelando_timeouts">Cancelando timeouts</h3>
+
+<p>Finalmente, se um timeout foi criado, você pode cancelá-lo antes que o tempo especificado tenha passado chamando <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout">clearTimeout()</a></code>, passando para o identificador a chamada <code>setTimeout()</code> como um parâmetreo. então para cancelar o timeout acima, você fará isso:</p>
+
+<pre class="brush: js notranslate">clearTimeout(myGreeting);</pre>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: Veja <code><a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/greeter-app.html">greeter-app.html</a></code> para uma demonstração mais desenvolvida que te permite colocar o nome da pessoa a dizer oi em um formulário, e cancelar a saudação usando um botão separado (<a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/greeter-app.html">veja aqui o código fonte</a>).</p>
+</div>
+
+<h2 id="setInterval">setInterval()</h2>
+
+<p><code>setTimeout()</code> funciona perfeitamento quando você precisa executar algum código depois de um período de tempo. Mas o que acontece quando voc~e precisa executar o código de novo e de novo — por exemplo, no caso de uma animação?</p>
+
+<p>É aí que o <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code> entra. Ele funciona de uma maneira muito similar à <code>setTimeout()</code>, exceto que a função que você passar como primeiro parâmetro é executada repetidamente em não menos que um número determinado de milissegundos dado no segundo parâmetro, ao invés de apenas uma vez. Você também pode passar qualquer parâmetro sendo executado como um parâmetro subsequente da chamada de <code>setInterval()</code>.</p>
+
+<p>Vamos dar uma olhada em um exemplo. A função a seguir cria um novo objeto <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date()</a></code>, tira uma string de tempo usando <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString">toLocaleTimeString()</a></code>, e depois a mostra naUI. Em seguida, ela executa a função uma vez por segundo usando <code>setInterval()</code>, criando o efeito de um relógio digital que é atualizado uma vez por segundo (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">veja aqui</a>, e também <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">veja o código</a>):</p>
+
+<pre class="brush: js notranslate">function displayTime() {
+ let date = new Date();
+ let time = date.toLocaleTimeString();
+ document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);</pre>
+
+<p>Assim como o <code>setTimeout()</code>, o <code>setInterval()</code> também retorna um valor identificador que você pode usar depois para cancelar o intervalo.</p>
+
+<h3 id="Cancelando_intervalos">Cancelando intervalos</h3>
+
+<p><code>setInterval()</code> continua sua execução para sempre, a menos que você faça algo sobre isso. Você provavelmente quer um jeito de parar tais tarefas, do contrário você pode acabar com error quando o navegador não puder completar outras versões futuras da tarefa, ou se a animação acabar. Você pode fazer isso do mesmo jeito que você para timeouts — passando o identificador retornado por <code>setInterval()</code> para a função <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval">clearInterval()</a></code>:</p>
+
+<pre class="brush: js notranslate">const myInterval = setInterval(myFunction, 2000);
+
+clearInterval(myInterval);</pre>
+
+<h4 id="Aprendizado_ativo_Criando_seu_próprio_cronômetro!">Aprendizado ativo: Criando seu próprio cronômetro!</h4>
+
+<p>Com tudo isso dito, nós temos um desafio para você. Faça uma cópia do nosso exemplo <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">setInterval-clock.html</a></code>, e o modifique para criar seu próprio cronômetro.</p>
+
+<p>Você precisa mostrar um tempo na tela como antes, mas nesse ememplo você vai precisar de:</p>
+
+<ul>
+ <li>Um botão de início para fazer o cronômetro começar a contar.</li>
+ <li>Um botâo de parar para parar ou pausar o tempo.</li>
+ <li>Um botão de "reset" para resetar o tempo em 0.</li>
+ <li>O display do tempo para mostrar o número de sgundos passados.</li>
+</ul>
+
+<p>Here's a few hints for you:</p>
+
+<ul>
+ <li>You can structure and style the button markup however you like; just make sure you use semantic HTML, with hooks to allow you to grab the button references using JavaScript.</li>
+ <li>You probably want to create a variable that starts at <code>0</code>, then increments by one every second using a constant loop.</li>
+ <li>It is easier to create this example without using a <code>Date()</code> object, like we've done in our version, but less accurate — you can't guarantee that the callback will fire after exactly <code>1000</code>ms. A more accurate way would be to run <code>startTime = Date.now()</code> to get a timestamp of exactly when the user clicked the start button, and then do <code>Date.now() - startTime</code> to get the number of milliseconds after the start button was clicked.</li>
+ <li>You also want to calculate the number of hours, minutes, and seconds as separate values, and then show them together in a string after each loop iteration. From the second counter, you can work out each of these.</li>
+ <li>How would you calculate them? Have a think about it:
+ <ul>
+ <li>The number of seconds in an hour is <code>3600</code>.</li>
+ <li>The number of minutes will be the amount of seconds left over when all of the hours have been removed, divided by <code>60</code>.</li>
+ <li>The number of seconds will be the amount of seconds left over when all of the minutes have been removed.</li>
+ </ul>
+ </li>
+ <li>You'll want to include a leading zero on your display values if the amount is less than <code>10</code>, so it looks more like a traditional clock/watch.</li>
+ <li>To pause the stopwatch, you'll want to clear the interval. To reset it, you'll want to set the counter back to <code>0</code>, clear the interval, and then immediately update the display.</li>
+ <li>You probably ought to disable the start button after pressing it once, and enable it again after you've stopped/reset it. Otherwise multiple presses of the start button will apply multiple <code>setInterval()</code>s to the clock, leading to wrong behavior.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you get stuck, you can <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-stopwatch.html">find our version here</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-stopwatch.html">source code</a> also).</p>
+</div>
+
+<h2 id="Coisas_para_se_manter_em_mente_sobre_o_setTimeout_e_o_setInterval">Coisas para se manter em mente sobre o setTimeout() e o setInterval()</h2>
+
+<p>Existem algumas coisinhas que devemos sempre lembrar quando estamos trabalhando com <code>setTimeout()</code> e<code>setInterval()</code>:</p>
+
+<h3 id="Timeouts_recursivos">Timeouts recursivos</h3>
+
+<p>Há outra maneira de usar o  <code>setTimeout()</code>: você pode chamá-lo recusivamnete para executar o mesmo código repetidas vezes, ao invés de usar o <code>setInterval()</code>.</p>
+
+<p>O exemplo abaixo usa um <code>setTimeout()</code> recursivo para executar a função passada a cada <code>100</code> millissegundos:</p>
+
+<pre class="brush: js notranslate">let i = 1;
+
+setTimeout(function run() {
+ console.log(i);
+ i++;
+ setTimeout(run, 100);
+}, 100);</pre>
+
+<p>Compare the above example to the following one — this uses <code>setInterval()</code> to accomplish the same effect:</p>
+
+<pre class="brush: js notranslate">let i = 1;
+
+setInterval(function run() {
+ console.log(i);
+ i++
+}, 100);</pre>
+
+<h4 id="Qual_a_diferença_entre_o_setTimeout_recursivo_e_o_setInterval">Qual a diferença entre o <code>setTimeout()</code> recursivo e o <code>setInterval()</code>?</h4>
+
+<p>A diferença entre as duas versões é bem sútil.</p>
+
+<ul>
+ <li>O <code>setTimeout()</code> recursivo garante que o mesmo intervalo entre as execuções (por exemplo, <code>100</code>ms no exemplo acima). O código será executado, depois esperar <code>100</code> milissegundos antes de fazer isso de novo— então o intervalo será o mesmo, idependente do tempo que o código leva para ser executado.</li>
+ <li>O exemplo usando <code>setInterval()</code> faz as coisas um pouco diferentes.O intervalo escolhido inclui o tempo necessário para executar o código que você deseja executar. Digamos que o código leva <code>40</code> milissegundos de execução — o intervalo acaba levando apenas <code>60</code> milissegundos.</li>
+ <li>Quando usamos o <code>setTimeout()</code> recursivamente, cada iteração pode calcular um delay diferente antes de executar a próxima iteração. Em outras palavras, o valor do segundo parâmetro pode especificar um tempo diferente em milissegundos para esperar antes de rodar o código de novo.</li>
+</ul>
+
+<p>Quando seu código tem o potencial para levar mais tempo do que lhe foi atribuido, é melhor usar o <code>setTimeout()</code> recursivo — isso irá manter o intervalo de tempo constant entre execuções independente do quanto tempo o código levar para ser executado, e você não terá erros.</p>
+
+<h3 id="Timeouts_imediatos">Timeouts imediatos</h3>
+
+<p>Usar zero como o valor para <code>setTimeout()</code> faz a execução da callback ser o mais rápido o possível, mas apenas depois que a main thread for terminada.</p>
+
+<p>Por exemplo, o código abaixo (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/zero-settimeout.html">veja funcionar aqui</a>) mostra um alert que contém um <code>"Hello"</code>, depois um  alert que contém <code>"World"</code> assim que você clicar em OK no primeiro alerta.</p>
+
+<pre class="brush: js notranslate">setTimeout(function() {
+ alert('World');
+}, 0);
+
+alert('Hello');</pre>
+
+<p>Isso pode ser útil em casos onde você quer fazer um bloco de código ser executado assim que a main thread acabar o seu processamento — colocar no loop de eventos async, assim ele vai ser executado logo depois.</p>
+
+<h3 id="Cancelando_com_clearTimeout_ou_clearInterval">Cancelando com clearTimeout() ou clearInterval()</h3>
+
+<p><code>clearTimeout()</code> e <code>clearInterval()</code> usam a mesma lista de entradas para cancelamento. Isso significa que você pode usar os dois para cancelar um <code>setTimeout()</code> ou <code>setInterval()</code>.</p>
+
+<p>Mas mesmo assim, você deve usar o <code>clearTimeout()</code> para entradas <code>setTimeout()</code> e <code>clearInterval()</code> para entradas <code>setInterval()</code>. Isso evita confusões.</p>
+
+<h2 id="requestAnimationFrame">requestAnimationFrame()</h2>
+
+<p><code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code> é uma função de loop especializada criada para executar animações com eficiência no navegador. Ela é basicamente a versão moderna de <code>setInterval()</code> — ela executa um bloco de código específico antes que o navegador renove o display, permitindo que uma animação seja executada em um framerate adequado independente do ambiente em que está sendo executada.</p>
+
+<p>Ela foi criada em resposta à problemas ocorridos com <code>setInterval()</code>, que por exemplo não roda em uma taxa de quadros otimizada para o dispositivo, e às vezes diminui os frames, continua a rodar mesmo se a guia não esiver ativa ou se a animação for rolada para fora da página, etc.</p>
+
+<p>(<a href="http://creativejs.com/resources/requestanimationframe/index.html">Leia mais sobre isso em CreativeJS</a>.)</p>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: Você pode encontrar exemplos do uso de <code>requestAnimationFrame()</code> em outros lugares do curso — por exemplo em <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a>, e <a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a>.</p>
+</div>
+
+<p>O método toma como argumentos uma callback a  ser invocada antes da renovação. Esse é o padrão geral que você verá usado em:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ // Drawing code goes here
+ requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<p>A ideia é definir uma função em que sua animação é atualizada (e.g. seus spritas se movem, a pontuação é atuializada, dados são recarregados, etc). Depois, você inicia o processo. No final do bloco da função você chama  <code>requestAnimationFrame()</code> com a referência da função passada como parâmetro, e isso instrui o navegador a chamar a função de novo na próxima renovação. Isso é executado continuamente, já que o código está chamando <code>requestAnimationFrame()</code> recursivamente.</p>
+
+<div class="blockIndicator note">
+<p><strong>Nota</strong>: Se você quer realizar algum tipo de animação na DOM constantemente, <a href="/en-US/docs/Web/CSS/CSS_Animations">Animações CSS</a> são provavelemente mais rápidas. elas são calculadas diretamente pelo código interno do navegador, ao invés de JavaScript.</p>
+
+<p>Se, no entanto, você está fazendo algo mais complexo e envolvendo objetos que não são diretamente assessados da DOM (como <a href="/en-US/docs/Web/API/Canvas_API">2D Canvas API</a> ou objetos <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a>), <code>requestAnimationFrame()</code> é a melhor opção na maioria dos casos</p>
+</div>
+
+<h3 id="Qual_a_velocidade_da_sua_animação">Qual a velocidade da sua animação?</h3>
+
+<p>A suavidade da sua animação é diretamente dependente na frame rate da sua animação e é medida em frames per second (fps). The smoothness of your animation is directly dependent on your animation's frame rate and it is measured in frames per second (fps). Quanto maior esse número, mais suave será a sua animação, até certo ponto.</p>
+
+<p>Já que a maioria das tela tem uma taxa de atualização de 60Hz, a frame rate mais rápida que você pode ter é de 60fps quando trabalhando com web browsers. No entanto, mais frames significa mais processamento, o que pode ser causar uma queda de quadros e travamento.</p>
+
+<p>Se você tem um monitos com uma taxa de atualização de 60Hz e você quer atingir 60FPS você tem pelo menos 16.7 milissegundos (<code>1000 / 60</code>) para executar sua animação em cada frame. Isso é um lembrete de que você vai precisar estar atento à quantidade de código que você vai tentar executar em cada iteração do loop de animação.</p>
+
+<p><code>requestAnimationFrame()</code> sempre tenta ficar o mais próximo possível de 60 FPS. Às vezes, isso não é possível — se você tem uma animação bem complexa e você está executando ela em um computador lento, sua frame rate será menor. Em todos os casos, o <code>requestAnimationFrame()</code> sempre vai fazer o melhor que pode com o que ele tem dísponivel.</p>
+
+<h3 id="Como_o_requestAnimationFrame_se_diferencia_de_setInterval_e_setTimeout">Como o requestAnimationFrame() se diferencia de setInterval() e setTimeout()?</h3>
+
+<p>Vamos falar um pouco sobre como o método <code>requestAnimationFrame()</code> se diferencia dos outros métodos vistos anteriormente. Olhando com o código anterior:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ // Drawing code goes here
+ requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<p>Vamos ver isso usando o <code>setInterval()</code>:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ // Drawing code goes here
+}
+
+setInterval(draw, 17);</pre>
+
+<p>Como foi dito anteriormente, você não especifica um intervalo de tempo para <code>requestAnimationFrame()</code>. O método se executa o mais rápido e suave o possível nas condições atuais. O navegador também não perde tempo executando uma animação se ela está fora da tela por algum motivo, etc.</p>
+
+<p><code>setInterval()</code>, por outro lado, exige que um  intervalo de tempo seja especificado. Nós chegamos ao valor final de 17 por meio da formula <em>1000 milliseconds / 60Hz</em>, e depois arredondamos o resultado. Arredondar é uma boa ideia; se você tivesse arredondado para baixo, o navegador pode tentar executar a animação mais rápido do que 60  FPS, e não faria nenhuma diferênça na suavidade da animação de qualquer forma. Como foi dito antes, 60Hz é a taxa de atualização padrão.</p>
+
+<h3 id="Incluindo_um_timestamp">Incluindo um timestamp</h3>
+
+<p>A callback passada para a função <code>requestAnimationFrame()</code> pode ser dada um parâmetro támbem: um valor <em>timestamp</em>, que representa o tempo desde que o  <code>requestAnimationFrame()</code> começou a rodar.</p>
+
+<p>Isso é útil, permite que você execute coisas em  um tempo específico e em passo constante, independente do quão rápido ou lento é o seu dispositivo. O padão geral que você usaria se parece um pouco com isso:</p>
+
+<pre class="brush: js notranslate">let startTime = null;
+
+function draw(timestamp) {
+ if (!startTime) {
+ startTime = timestamp;
+ }
+
+ currentTime = timestamp - startTime;
+
+ // Do something based on current time
+
+ requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<h3 id="Suporte_do_navegador">Suporte do navegador</h3>
+
+<p><code>requestAnimationFrame()</code> é suportado em navegadores mais recentes do que <code>setInterval()</code>/<code>setTimeout()</code>.  Curiosamente, está disponível no Internet Explorer 10 e além.</p>
+
+<p>Então, você não precisa dar suporte para versões mais velhas do IE, não há poruqe não usar o  <code>requestAnimationFrame()</code>.</p>
+
+<h3 id="Um_exemplo_simples">Um exemplo simples</h3>
+
+<p>Enough with the theory! Let's build your own personal <code>requestAnimationFrame()</code> example. You're going to create a simple "spinner animation"—the kind you might see displayed in an app when it is busy connecting to the server, etc.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: In a real world example, you should probably use CSS animations to run this kind of simple animation. However, this kind of example is very useful to demonstrate <code>requestAnimationFrame()</code> usage, and you'd be more likely to use this kind of technique when doing something more complex such as updating the display of a game on each frame.</p>
+</div>
+
+<ol>
+ <li>
+ <p>Grab a basic HTML template (<a href="https://github.com/mdn/learning-area/blob/master/html/introduction-to-html/getting-started/index.html">such as this one</a>).</p>
+ </li>
+ <li>
+ <p>Put an empty {{htmlelement("div")}} element inside the {{htmlelement("body")}}, then add a ↻ character inside it. This is circular arrow character will act as our spinner for this example.</p>
+ </li>
+ <li>
+ <p>Apply the following CSS to the HTML template (in whatever way you prefer). This sets a red background on the page, sets the <code>&lt;body&gt;</code> height to <code>100%</code> of the {{htmlelement("html")}} height, and centers the <code>&lt;div&gt;</code> inside the <code>&lt;body&gt;</code>, horizontally and vertically.</p>
+
+ <pre class="brush: css notranslate">html {
+ background-color: white;
+ height: 100%;
+}
+
+body {
+ height: inherit;
+ background-color: red;
+ margin: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+div {
+ display: inline-block;
+ font-size: 10rem;
+}</pre>
+ </li>
+ <li>
+ <p>Insert a {{htmlelement("script")}} element just above the <code>&lt;/body&gt;</code> tag.</p>
+ </li>
+ <li>
+ <p>Insert the following JavaScript inside your <code>&lt;script&gt;</code> element. Here, you're storing a reference to the <code>&lt;div&gt;</code> inside a constant, setting a <code>rotateCount</code> variable to <code>0</code>, setting an uninitialized variable that will later be used to contain a reference to the <code>requestAnimationFrame()</code> call, and setting a <code>startTime</code> variable to <code>null</code>, which will later be used to store the start time of the <code>requestAnimationFrame()</code>.</p>
+
+ <pre class="brush: js notranslate">const spinner = document.querySelector('div');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+</pre>
+ </li>
+ <li>
+ <p>Below the previous code, insert a <code>draw()</code> function that will be used to contain our animation code, which includes the <code>timestamp</code> parameter:</p>
+
+ <pre class="brush: js notranslate">function draw(timestamp) {
+
+}</pre>
+ </li>
+ <li>
+ <p>Inside <code>draw()</code>, add the following lines. They will define the start time if it is not defined already (this will only happen on the first loop iteration), and set the <code>rotateCount</code> to a value to rotate the spinner by (the current timestamp, take the starting timestamp, divided by three so it doesn't go too fast):</p>
+
+ <pre class="brush: js notranslate"> if (!startTime) {
+ startTime = timestamp;
+ }
+
+ rotateCount = (timestamp - startTime) / 3;
+</pre>
+ </li>
+ <li>
+ <p>Below the previous line inside <code>draw()</code>, add the following block — this checks to see if the value of <code>rotateCount</code> is above <code>359</code> (e.g. <code>360</code>, a full circle). If so, it sets the value to its modulo of 360 (i.e. the remainder left over when the value is divided by <code>360</code>) so the circle animation can continue uninterrupted, at a sensible, low value. Note that this isn't strictly necessary, but it is easier to work with values of 0–359 degrees than values like <code>"128000 degrees"</code>.</p>
+
+ <pre class="brush: js notranslate">if (rotateCount &gt; 359) {
+ rotateCount %= 360;
+}</pre>
+ </li>
+ <li>Next, below the previous block add the following line to actually rotate the spinner:
+ <pre class="brush: js notranslate">spinner.style.transform = `rotate(${rotateCount}deg)`;</pre>
+ </li>
+ <li>
+ <p>At the very bottom inside the <code>draw()</code> function, insert the following line. This is the key to the whole operation — you are setting the variable defined earlier to an active <code>requestAnimation()</code> call, which takes the <code>draw()</code> function as its parameter. This starts the animation off, constantly running the <code>draw()</code> function at a rate as near 60 FPS as possible.</p>
+
+ <pre class="brush: js notranslate">rAF = requestAnimationFrame(draw);</pre>
+ </li>
+</ol>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: You can find this <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">example live on GitHub</a>. (You can see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">source code</a>, also.)</p>
+</div>
+
+<h3 id="Clearing_a_requestAnimationFrame_call">Clearing a requestAnimationFrame() call</h3>
+
+<p>Clearing a <code>requestAnimationFrame()</code> call can be done by calling the corresponding <code>cancelAnimationFrame()</code> method. (Note that the function name starts with "cancel", not "clear" as with the "set..." methods.) </p>
+
+<p>Just pass it the value returned by the <code>requestAnimationFrame()</code> call to cancel, which you stored in the variable <code>rAF</code>:</p>
+
+<pre class="brush: js notranslate">cancelAnimationFrame(rAF);</pre>
+
+<h3 id="Active_learning_Starting_and_stopping_our_spinner">Active learning: Starting and stopping our spinner</h3>
+
+<p>In this exercise, we'd like you to test out the <code>cancelAnimationFrame()</code> method by taking our previous example and updating it, adding an event listener to start and stop the spinner when the mouse is clicked anywhere on the page.</p>
+
+<p>Some hints:</p>
+
+<ul>
+ <li>A <code>click</code> event handler can be added to most elements, including the document <code>&lt;body&gt;</code>. It makes more sense to put it on the <code>&lt;body&gt;</code> element if you want to maximize the clickable area — the event bubbles up to its child elements.</li>
+ <li>You'll want to add a tracking variable to check whether the spinner is spinning or not, clearing the animation frame if it is, and calling it again if it isn't.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Try this yourself first; if you get really stuck, check out of our <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/start-and-stop-spinner.html">live example</a> and <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/start-and-stop-spinner.html">source code</a>.</p>
+</div>
+
+<h3 id="Throttling_a_requestAnimationFrame_animation">Throttling a requestAnimationFrame() animation</h3>
+
+<p>One limitation of <code>requestAnimationFrame()</code> is that you can't choose your frame rate. This isn't a problem most of the time, as generally you want your animation to run as smoothly as possible. But what about when you want to create an old school, 8-bit-style animation?</p>
+
+<p>This was a problem, for example, in the Monkey Island-inspired walking animation from our <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing Graphics</a> article:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/loops_animation/7_canvas_walking_animation.html", '100%', 260)}}</p>
+
+<p>In this example, you have to animate both the position of the character on the screen, and the sprite being shown. There are only 6 frames in the sprite's animation. If you showed a different sprite frame for every frame displayed on the screen by <code>requestAnimationFrame()</code>, Guybrush would move his limbs too fast and the animation would look ridiculous. This example therefore throttles the rate at which the sprite cycles its frames using the following code:</p>
+
+<pre class="brush: js notranslate">if (posX % 13 === 0) {
+ if (sprite === 5) {
+ sprite = 0;
+ } else {
+ sprite++;
+ }
+}</pre>
+
+<p>So the code only cycles the sprite once every 13 animation frames.</p>
+
+<p>...Actually, it's about every 6.5 frames, as we update <code>posX</code> (character's position on the screen) by two each frame:</p>
+
+<pre class="brush: js notranslate">if (posX &gt; width/2) {
+ newStartPos = -( (width/2) + 102 );
+ posX = Math.ceil(newStartPos / 13) * 13;
+ console.log(posX);
+} else {
+ posX += 2;
+}</pre>
+
+<p>This is the code that calculates how to update the position in each animation frame.</p>
+
+<p>The method you use to throttle your animation will depend on your particular code. For instance, in the earlier spinner example, you could make it appear to move slower by only increasing <code>rotateCount</code> by one on each frame, instead of two.</p>
+
+<h2 id="Active_learning_a_reaction_game">Active learning: a reaction game</h2>
+
+<p>For the final section of this article, you'll create a 2-player reaction game. The game will have two players, one of whom controls the game using the <kbd>A</kbd> key, and the other with the <kbd>L</kbd> key.</p>
+
+<p>When the <em>Start</em> button is pressed, a spinner like the one we saw earlier is displayed for a random amount of time between 5 and 10 seconds. After that time, a message will appear saying <code>"PLAYERS GO!!"</code> — once this happens, the first player to press their control button will win the game.</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}</p>
+
+<p>Let's work through this:</p>
+
+<ol>
+ <li>
+ <p>First of all, download the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/reaction-game-starter.html">starter file for the app</a>. This contains the finished HTML structure and CSS styling, giving us a game board that shows the two players' information (as seen above), but with the spinner and results paragraph displayed on top of one another. You just have to write the JavaScript code.</p>
+ </li>
+ <li>
+ <p>Inside the empty {{htmlelement("script")}} element on your page, start by adding the following lines of code that define some constants and variables you'll need in the rest of the code:</p>
+
+ <pre class="brush: js notranslate">const spinner = document.querySelector('.spinner p');
+const spinnerContainer = document.querySelector('.spinner');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+const btn = document.querySelector('button');
+const result = document.querySelector('.result');</pre>
+
+ <p>In order, these are:</p>
+
+ <ol>
+ <li>A reference to the spinner, so you can animate it.</li>
+ <li>A reference to the {{htmlelement("div")}} element that contains the spinner, used for showing and hiding it.</li>
+ <li>A rotate count. This determines how much you want to show the spinner rotated on each frame of the animation.</li>
+ <li>A null start time. This will be populated with a start time when the spinner starts spinning.</li>
+ <li>An uninitialized variable to later store the {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} call that animates the spinner.</li>
+ <li>A reference to the Start button.</li>
+ <li>A reference to the results paragraph.</li>
+ </ol>
+ </li>
+ <li>
+ <p>Next, below the previous lines of code, add the following function. It simply takes two numbers and returns a random number between the two. You'll need this to generate a random timeout interval later on.</p>
+
+ <pre class="brush: js notranslate">function random(min,max) {
+ var num = Math.floor(Math.random()*(max-min)) + min;
+ return num;
+}</pre>
+ </li>
+ <li>
+ <p>Next add  the <code>draw()</code> function, which animates the spinner. This is very similar to the version from the simple spinner example, earlier:</p>
+
+ <pre class="brush: js notranslate">function draw(timestamp) {
+ if(!startTime) {
+ startTime = timestamp;
+ }
+
+ rotateCount = (timestamp - startTime) / 3;
+
+ if(rotateCount &gt; 359) {
+ rotateCount %= 360;
+ }
+
+ spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
+ rAF = requestAnimationFrame(draw);
+}</pre>
+ </li>
+ <li>
+ <p>Now it is time to set up the initial state of the app when the page first loads. Add the following two lines, which simply hide the results paragraph and spinner container using <code>display: none;</code>.</p>
+
+ <pre class="brush: js notranslate">result.style.display = 'none';
+spinnerContainer.style.display = 'none';</pre>
+ </li>
+ <li>
+ <p>Next, define a <code>reset()</code> function, which sets the app back to the original state required to start the game again after it has been played. Add the following at the bottom of your code:</p>
+
+ <pre class="brush: js notranslate">function reset() {
+ btn.style.display = 'block';
+ result.textContent = '';
+ result.style.display = 'none';
+}</pre>
+ </li>
+ <li>
+ <p>Okay, enough preparation!  It's time to make the game playable! Add the following block to your code. The <code>start()</code> function calls <code>draw()</code> to start the spinner spinning and display it in the UI, hides the <em>Start</em> button so you can't mess up the game by starting it multiple times concurrently, and runs a <code>setTimeout()</code> call that runs a <code>setEndgame()</code> function after a random interval between 5 and 10 seconds has passed. The following block also adds an event listener to your button to run the <code>start()</code> function when it is clicked.</p>
+
+ <pre class="brush: js notranslate">btn.addEventListener('click', start);
+
+function start() {
+ draw();
+ spinnerContainer.style.display = 'block';
+ btn.style.display = 'none';
+ setTimeout(setEndgame, random(5000,10000));
+}</pre>
+
+ <div class="blockIndicator note">
+ <p><strong>Note</strong>: You'll see this example is calling <code>setTimeout()</code> without storing the return value. (So, not <code>let myTimeout = setTimeout(functionName, interval)</code>.) </p>
+
+ <p>This works just fine, as long as you don't need to clear your interval/timeout at any point. If you do, you'll need to save the returned identifier!</p>
+ </div>
+
+ <p>The net result of the previous code is that when the <em>Start</em> button is pressed, the spinner is shown and the players are made to wait a random amount of time before they are asked to press their button. This last part is handled by the <code>setEndgame()</code> function, which you'll define next.</p>
+ </li>
+ <li>
+ <p>Add the following function to your code next:</p>
+
+ <pre class="brush: js notranslate">function setEndgame() {
+ cancelAnimationFrame(rAF);
+ spinnerContainer.style.display = 'none';
+ result.style.display = 'block';
+ result.textContent = 'PLAYERS GO!!';
+
+ document.addEventListener('keydown', keyHandler);
+
+ function keyHandler(e) {
+ console.log(e.key);
+ if(e.key === 'a') {
+ result.textContent = 'Player 1 won!!';
+ } else if(e.key === 'l') {
+ result.textContent = 'Player 2 won!!';
+ }
+
+ document.removeEventListener('keydown', keyHandler);
+ setTimeout(reset, 5000);
+ };
+}</pre>
+
+ <p>Stepping through this:</p>
+
+ <ol>
+ <li>First, cancel the spinner animation with {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}} (it is always good to clean up unneeded processes), and hide the spinner container.</li>
+ <li>Next, display the results paragraph and set its text content to "PLAYERS GO!!" to signal to the players that they can now press their button to win.</li>
+ <li>Attach a <code><a href="/en-US/docs/Web/API/Document/keydown_event">keydown</a></code> event listener to the document. When any button is pressed down, the <code>keyHandler()</code> function is run.</li>
+ <li>Inside <code>keyHandler()</code>, the code includes the event object as a parameter (represented by <code>e</code>) — its {{domxref("KeyboardEvent.key", "key")}} property contains the key that was just pressed, and you can use this to respond to specific key presses with specific actions.</li>
+ <li>Log <code>e.key</code> to the console, which is a useful way of finding out the <code>key</code> value of different keys you are pressing.</li>
+ <li>When <code>e.key</code> is "a", display a message to say that Player 1 won, and when <code>e.key</code> is "l", display a message to say Player 2 won. (<strong>Note:</strong> This will only work with lowercase a and l — if an uppercase A or L is submitted (the key plus <kbd>Shift</kbd>), it is counted as a different key!)</li>
+ <li>Regardless of which one of the player control keys was pressed,  remove the <code>keydown</code> event listener using {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} so that once the winning press has happened, no more keyboard input is possible to mess up the final game result. You also use <code>setTimeout()</code> to call <code>reset()</code> after 5 seconds — as explained earlier, this function resets the game back to its original state so that a new game can be started.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>That's it—you're all done!</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you get stuck, check out <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html">our version of the reaction game</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/reaction-game.html">source code</a> also).</p>
+</div>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>So that's it — all the essentials of async loops and intervals covered in one article. You'll find these methods useful in a lot of situations, but take care not to overuse them! Because they still run on the main thread, heavy and intensive callbacks (especially those that manipulate the DOM) can really slow down a page if you're not careful.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">General asynchronous programming concepts</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>