aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/guide/usando_promises/index.html
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/web/javascript/guide/usando_promises/index.html
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/pt-br/web/javascript/guide/usando_promises/index.html')
-rw-r--r--files/pt-br/web/javascript/guide/usando_promises/index.html269
1 files changed, 269 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/guide/usando_promises/index.html b/files/pt-br/web/javascript/guide/usando_promises/index.html
new file mode 100644
index 0000000000..a0dd09c8c2
--- /dev/null
+++ b/files/pt-br/web/javascript/guide/usando_promises/index.html
@@ -0,0 +1,269 @@
+---
+title: Usando promises
+slug: Web/JavaScript/Guide/Usando_promises
+tags:
+ - Guía
+ - Intermediário
+ - JavaScript
+ - Promise
+ - Promises
+translation_of: Web/JavaScript/Guide/Using_promises
+---
+<div>{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div>
+
+<p class="summary">Uma {{jsxref("Promise")}} é um objeto que representa a eventual conclusão ou falha de uma operação assincrona. Como a maioria das pessoas consomem promisses já criadas, este guia explicará o consumo de promisses devolvidas antes de explicar como criá-las.</p>
+
+<p>Essencialmente, uma promise é um objeto retornado para o qual você adiciona callbacks, em vez de passar callbacks para uma função.</p>
+
+<p>Por exemplo, em vez de uma função old-style que espera dois callbacks, e chama um deles em uma eventual conclusão ou falha:</p>
+
+<pre class="brush: js line-numbers language-html language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">successCallback</span><span class="punctuation token">(</span>result<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">"It succeeded with "</span> <span class="operator token">+</span> result<span class="punctuation token">)</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+<span class="keyword token">function</span> <span class="function token">failureCallback</span><span class="punctuation token">(</span>error<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">"It failed with "</span> <span class="operator token">+</span> error<span class="punctuation token">)</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+<span class="function token">doSomething</span><span class="punctuation token">(</span>successCallback<span class="punctuation token">,</span> failureCallback<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+
+<p>…funções modernas retornam uma promisse e então você pode adicionar seus callbacks:</p>
+
+<pre class="brush: js line-numbers language-html language-js"><code class="language-js"><span class="keyword token">const</span> promise <span class="operator token">=</span> <span class="function token">doSomething</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
+promise<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span>successCallback<span class="punctuation token">,</span> failureCallback<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+
+<p>…ou simplesmente:</p>
+
+<pre class="brush: js line-numbers language-html language-js"><code class="language-js"><span class="function token">doSomething</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span>successCallback<span class="punctuation token">,</span> failureCallback<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+
+<p>Nós chamamos isso de <em>chamada de função assincrona</em>. Essa convenção tem várias vantagens. Vamos explorar cada uma delas.</p>
+
+<h2 id="Garantias">Garantias</h2>
+
+<p>Ao contrário dos callbacks com retornos de funções old-style, uma promisse vem com algumas garantias:</p>
+
+<ul>
+ <li>Callbacks nunca serão chamados antes da <a href="/en-US/docs/Web/JavaScript/EventLoop#Run-to-completion">conclusão da execução atual</a> do loop de eventos do JavaScript. </li>
+ <li>Callbacks adicionadas com .then mesmo <em>depois</em> do sucesso ou falha da operação assincrona, serão chamadas, como acima.</li>
+ <li>Multiplos callbacks podem ser adicionados chamando-se .then várias vezes, para serem executados independentemente da ordem de inserção.</li>
+</ul>
+
+<p>Mas o benefício mais imediato da promises é o encadeamento.</p>
+
+
+
+<h2 id="Encadeamento">Encadeamento</h2>
+
+<p>Uma necessidade comum é executar duas ou mais operações assincronas consecutivas, onde cada operação subsequente começa quando a operação anterior é bem sucedida, com o resultado do passo anterior. Nós conseguimos isso criando uma <em>cadeia de promises</em>.</p>
+
+<p>Aqui está a magica: a função <code>then</code> retorna uma nova promise, diferente da original:</p>
+
+<pre class="brush: js">const promise = doSomething();
+const promise2 = promise.then(successCallback, failureCallback);
+</pre>
+
+<p>ou</p>
+
+<pre class="brush: js">const promise2 = doSomething().then(successCallback, failureCallback);
+</pre>
+
+<p>Essa segunda promise representa a conclusão não apenas de <code>doSomething()</code>, mas também do <code>successCallback</code> ou <code>failureCallback</code> que você passou, que podem ser outras funções assincronas que retornam uma promise. Quando esse for o caso, quaisquer callbacks adicionados a <code>promise2</code> serão enfileiradas atrás da promise retornada por <code>successCallback</code> ou <code>failureCallback</code>.</p>
+
+<p>Basicamente, cada promise representa a completude de outro passo assíncrono na cadeia.</p>
+
+<p>Antigamente, realizar operações assíncronas comuns em uma linha levaria à clássica pirâmide da desgraça :</p>
+
+<pre class="brush: js">doSomething(function(result) {
+ doSomethingElse(result, function(newResult) {
+ doThirdThing(newResult, function(finalResult) {
+ console.log('Got the final result: ' + finalResult);
+ }, failureCallback);
+ }, failureCallback);
+}, failureCallback);
+</pre>
+
+<p>Ao invés disso, com funções modernas, nós atribuímos nossas callbacks às promises retornadas, formando uma <em>cadeia de promise</em>:</p>
+
+<pre class="brush: js">doSomething().then(function(result) {
+ return doSomethingElse(result);
+})
+.then(function(newResult) {
+ return doThirdThing(newResult);
+})
+.then(function(finalResult) {
+ console.log('Got the final result: ' + finalResult);
+})
+.catch(failureCallback);
+</pre>
+
+<p>Os argumentos para <code>then</code> são opcionais, e <code>catch(failureCallback)</code> é uma abreviação para <code>then(null, failureCallback)</code>. Você pode também pode ver isso escrito com <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a>:</p>
+
+<pre class="brush: js">doSomething()
+.then(result =&gt; doSomethingElse(result))
+.then(newResult =&gt; doThirdThing(newResult))
+.then(finalResult =&gt; {
+ console.log(`Got the final result: ${finalResult}`);
+})
+.catch(failureCallback);
+</pre>
+
+<p><strong>Importante: </strong>Sempre retorne um resultado, de outra forma as callbacks não vão capturar o resultado da promise anterior.</p>
+
+<h3 id="Encadeando_depois_de_um_catch">Encadeando depois de um catch</h3>
+
+<p>É possivel encadear <em>depois </em>de uma falha, i.e um <code>catch</code>, isso é muito útil para realizar novas ações mesmo depois de uma falha no encadeamento. Leia o seguinte exemplo: </p>
+
+<pre class="brush: js">new Promise((resolve, reject) =&gt; {
+ console.log('Initial');
+
+ resolve();
+})
+.then(() =&gt; {
+ throw new Error('Something failed');
+
+ console.log('Do this');
+})
+.catch(() =&gt; {
+ console.log('Do that');
+})
+.then(() =&gt; {
+ console.log('Do this whatever happened before');
+});
+</pre>
+
+<p>Isso vai produzir o seguinte texto:</p>
+
+<pre>Initial
+Do that
+Do this whatever happened before
+</pre>
+
+<p>Observe que o texto "Do this" não foi impresso por conta que o erro "Something failed" causou uma rejeição.</p>
+
+<h2 id="Propagação_de_erros">Propagação de erros</h2>
+
+<p>Na pirâmide da desgraça vista anteriormente, você pode se lembrar de ter visto <code>failureCallback</code> três vezes, em comparação a uma única vez no fim da corrente de promessas:</p>
+
+<pre class="brush: js">doSomething()
+.then(result =&gt; doSomethingElse(result))
+.then(newResult =&gt; doThirdThing(newResult))
+.then(finalResult =&gt; console.log(`Got the final result: ${finalResult}`))
+.catch(failureCallback);
+</pre>
+
+<p>Basicamente, uma corrente de promessas para se houver uma exceção, procurando por catch handlers no lugar. Essa modelagem de código segue bastante a maneira de como o código síncrono funciona:</p>
+
+<pre class="brush: js">try {
+ const result = syncDoSomething();
+ const newResult = syncDoSomethingElse(result);
+ const finalResult = syncDoThirdThing(newResult);
+ console.log(`Got the final result: ${finalResult}`);
+} catch(error) {
+ failureCallback(error);
+}
+</pre>
+
+<p>Essa simetria com código assíncrono resulta no <em>syntactic sugar</em> <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> presente no ECMAScript 2017:</p>
+
+<pre class="brush: js">async function foo() {
+ try {
+ const result = await doSomething();
+ const newResult = await doSomethingElse(result);
+ const finalResult = await doThirdThing(newResult);
+ console.log(`Got the final result: ${finalResult}`);
+ } catch(error) {
+ failureCallback(error);
+ }
+}
+</pre>
+
+<p>É construído sobre promesas, por exemplo, <code>doSomething()</code> é a mesma função que antes. Leia mais sobre a sintaxe <a href="https://developers.google.com/web/fundamentals/getting-started/primers/async-functions">aqui</a>.</p>
+
+<p>Por pegar todos os erros, até mesmo exceções jogadas(<em>thrown exceptions</em>) e erros de programação, as promises acabam por solucionar uma falha fundamental presente na pirâmide da desgraça dos callbacks. Essa característica é essencial para a composição funcional das operações assíncronas.</p>
+
+<h2 id="Criando_uma_Promise_em_torno_de_uma_callback_API_antiga">Criando uma Promise em torno de uma callback API antiga</h2>
+
+<p>Uma {{jsxref("Promise")}} pode ser criada do zero utilizando o seu construtor. Isto deve ser necessário apenas para o envolvimento de APIs antigas.</p>
+
+<p>Em um mundo ideal, todas as funções assincronas já retornariam promises. Infelizmente, algumas APIs ainda esperam que os retornos de suceso e/ou falha sejam passados da maneira antiga. O exemplo por excelência é o {{domxref("WindowTimers.setTimeout", "setTimeout()")}} function:</p>
+
+<pre class="brush: js">setTimeout(() =&gt; saySomething("10 seconds passed"), 10000);
+</pre>
+
+<p>Misturar chamadas de retorno e promeses de <em>old-style</em> é problemático. Se <code>saySomething</code> falhar ou contiver um erro de programação, nada o captura.</p>
+
+<p>Por sorte nós podemos envolve-la em uma promise. É uma boa prática envolver funções problemáticas no menor nivel possível, e nunca chama-las diretamente de novo:</p>
+
+<pre class="brush: js">const wait = ms =&gt; new Promise(resolve =&gt; setTimeout(resolve, ms));
+
+wait(10000).then(() =&gt; saySomething("10 seconds")).catch(failureCallback);
+</pre>
+
+<p>Basically, the promise constructor takes an executor function that lets us resolve or reject a promise manually. Since <code>setTimeout</code> doesn't really fail, we left out reject in this case.</p>
+
+<p>Basicamente, um construtor de promises pega uma função executora que nos deixa resolver ou rejeitar uma promise manualmente. Desde que <code>setTimeout</code> não venha a falhar, nos deixamos a rejeição de fora nesse caso</p>
+
+<h2 id="Composição">Composição</h2>
+
+<p>{{jsxref("Promise.resolve()")}} e {{jsxref("Promise.reject()")}} são atalhos para se criar manualmente uma promessa que já foi resolvida ou rejeitada, respectivamente. Isso pode ser útil em algumas situações.</p>
+
+<p>{{jsxref("Promise.all()")}} e {{jsxref("Promise.race()")}} são duas ferramentas de composição para se executar operações assíncronas em paralelo.</p>
+
+<p>Uma composição sequencial é possível usando JavaScript de uma forma esperta:</p>
+
+<pre class="brush: js">[func1, func2].reduce((p, f) =&gt; p.then(f), Promise.resolve());
+</pre>
+
+<p>Basicamente reduzimos um vetor de funções assíncronas a uma cadeia de promessas equivalentes a: <code>Promise.resolve().then(func1).then(func2);</code></p>
+
+<p>Isso também pode ser feito com uma função de composição reutilizável, que é comum em programação funcional:</p>
+
+<pre class="brush: js">const applyAsync = (acc,val) =&gt; acc.then(val);
+const composeAsync = (...funcs) =&gt; x =&gt; funcs.reduce(applyAsync, Promise.resolve(x));</pre>
+
+
+
+<p>A função composeAsync aceitará qualquer número de funções como argumentos e retornará uma nova função que aceita um valor incial a ser passado pelo pipeline de composição. Isso é benéfico porque alguma, ou todas as funções, podem ser assíncronas ou síncronas, e é garantido de que serão executadas na ordem correta.</p>
+
+<pre class="brush: js">const transformData = composeAsync(func1, asyncFunc1, asyncFunc2, func2);
+transformData(data);
+</pre>
+
+<p>No ECMAScript 2017, uma composição sequencial pode ser feita sde forma mais simples com async/await:</p>
+
+<pre class="brush: js">for (const f of [func1, func2]) {
+ await f();
+}
+</pre>
+
+<h2 id="Cronometragem">Cronometragem</h2>
+
+<p>Para evitar surpresas, funções passadas para <code>then</code> nunca serão chamadas sincronamente, mesmo com uma função ja resolvida:</p>
+
+<pre class="brush: js">Promise.resolve().then(() =&gt; console.log(2));
+console.log(1); // 1, 2
+</pre>
+
+<p>Instead of running immediately, the passed-in function is put on a microtask queue, which means it runs later when the queue is emptied at the end of the current run of the JavaScript event loop, i.e. pretty soon:</p>
+
+<p>Ao invés de rodar imediatamente, a função passada é colocada em uma micro tarefa, o que significa que ela roda depois que a fila estiver vazia no final do atual processo de evento de loop do Javascript, isto é muito em breve</p>
+
+<pre class="brush: js">const wait = ms =&gt; new Promise(resolve =&gt; setTimeout(resolve, ms));
+
+wait().then(() =&gt; console.log(4));
+Promise.resolve().then(() =&gt; console.log(2)).then(() =&gt; console.log(3));
+console.log(1); // 1, 2, 3, 4
+</pre>
+
+<h2 id="Ver_também">Ver também</h2>
+
+<ul>
+ <li>{{jsxref("Promise.then()")}}</li>
+ <li><a href="http://promisesaplus.com/">Promises/A+ specification</a></li>
+ <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li>
+ <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li>
+ <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</a></li>
+ <li><a href="http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">Nolan Lawson: We have a problem with promises — Common mistakes with promises</a></li>
+</ul>
+
+<p>{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</p>